Clint Berry

Full-stack Web Developer

Wannabe Entrepreneur

Build Desktop Apps With HTML Using Brackets Shell

Posted on 25 Jun 2013 in Desktop, HTML5 | 51 comments

branding_256 I recently posted on the state of native desktop apps in HTML5 and mentioned that at my company we chose to use Brackets-Shell as our native app solution. I want to go more in-depth into what brackets is and why we chose it as our solution. This will be the first of a series of posts dedicated to brackets-shell and customizing it for your native HTML desktop applications.

UPDATE: I Posted part 2 of the series: JavaScript and the Brackets Shell Environment

What is Brackets?

Brackets is an open-source code editor created by Adobe. What makes brackets so cool, though, is that the entire editor is written in HTML and JavaScript. This puts Brackets in a unique opportunity that allows pretty much any developer that would use the editor (HTML and JavaScript guys) to add to and improve the editor with the very languages they use on a regular basis. And while I don’t use brackets myself just yet (hard to leave Sublime Text) it is definitely on my radar and I may make that switch soon.

What is Brackets Shell?

Brackets Shell is what allows Brackets to be run as a desktop application. It takes Chromium Embedded Framework (CEF) and adds some extras along with an excellent build tool. The brackets-shell app is so well done, it made it easy for a web-developer like me to get my first ever C++ pull request accepted (I took credit for that whole pull request, but the windows portion was done by my good friend, Jordan).

Why Use Brackets Shell Instead of Other Solutions?

I’m glad you asked:

  • Very active development – Of all the HTML shells for the desktop, this one was the most active in terms of code being committed.
  • Backed by Adobe – A corporate sponsor doesn’t guarantee that the project will be around forever, but it is more promising than not having one
  • NodeJS Integration – The brackets team recently integrated NodeJS into the brackets shell which allows for some really awesome plugin capabilities without learning C++
  • The Build Process – Building cross platform desktop applications can be a pain. Unless someone went through all the pain for you and automated the whole thing, including the creation of the installer. And on top of that, did it in Grunt, which most JavaScript developers are already familiar with. But who would do that for you? The Brackets team did. Amazing.

Now on to the good stuff.

Test Your Application in Brackets Shell

The first thing you will want to do is test the shell to see if your HTML application runs in it. The quickest route to doing this is to download the latest Brackets editor and install it. The installer installs the brackets-shell along with the brackets HTML application. If you remove the HTML app then the when you run the brackets shell it will ask you for the location of your index.html file. If you choose your own index.html file from your own application, brackets shell will open that.

To remove the brackets HTML app on Windows, browse to the Brackets folder in your Program Files directory. Inside the Brackets folder there is a folder named ‘www’. Rename or delete that folder, then run Brackets. The file dialog will open prompting you to select your own index.html file.

On OSX, open the terminal and browse to your application directory. Applications in OSX are actually folders, and in terminal you can view their content. CD into the Brackets Sprint [sprint number].app folder and continue to the Contents directory. Inside there you will see the www folder. Delete or rename it and then run brackets. You will see the file dialog prompting you to select your own index.html file.

Building Brackets Shell

If your app runs well in brackets-shell your next step is to setup your computer to build brackets-shell. This is where the shell really shines. They have an amazing Grunt setup that allows you to run the build in one command. Brackets provides some great instructions on setting up your box here. Once you are setup, run `grunt build` from the command line and it should create a full build of brackets shell for you. So awesome.

Setup for Your App

This is where things get fun. Let’s make the shell be a full-on desktop app for our own software. Make sure you have followed the instructions for getting setup to build brackets-shell and then take these next steps:

  • Fork the Repo – I recommend you fork the bracket-shell repo on github so you have a place to persist your own changes. Once you do that, then check out your forked repo.
  • Make your app folder a sibling of the shell folder – The build scripts from brackets are setup to expect your HTML app source code to be in a sibling folder to the brackets-shell folder
  • Use Git for your HTML app – To use the build scripts provided by brackets, you need to be using Git with your source code. If you aren’t using git for your project, cd into your project folder and type `git init` and commit your project to the repo by doing `git add .` and then `git commit -m “Initial commit”`
  • Update grunt file – If your html application folder is called my-app, then you need to tell Grunt where it is. Edit Gruntfile.js in the root of the brackets-shell folder and change the config section git->www->repo from “../brackets” to “../my-app”, and also change www->files->cwd value by removing ‘src’ from the end of the file (assuming your index.html file is in the root of your project) then save the file.
    Screen Shot 2013-06-21 at 4.59.21 PM
    Screen Shot 2013-06-21 at 6.08.39 PM

Now you are all setup. To see what grunt commands you have available type in `grunt –help` at your terminal

> grunt --help
Available tasks
          full-build  Alias for "git", "create-project", "build",
                      "build-branch", "build-num", "build-sha", "stage",
                      "package" tasks.
           installer  Alias for "full-build", "build-installer" tasks.
               build  Build shell executable. Run 'grunt full-build' to update
                      repositories, build the shell and package www files.
           build-mac  Build mac shell
           build-win  Build windows shell
                 git  Pull specified repo branch from origin *
        build-branch  Write www repo branch to config property
           build-num  Compute www repo build number and set config property
           build-sha  Write www repo SHA to config property
               stage  Stage release files
           stage-mac  Stage mac executable files
           stage-win  Stage win executable files
             package  Package www files
        write-config  Update version data in www config.json payload
     build-installer  Build installer
 build-installer-mac  Build mac installer
 build-installer-win  Build windows installer
          set-sprint  Update occurrences of sprint number for all native
                      installers and binaries
                 cef  Download and setup CEF
           cef-clean  Removes CEF binaries and linked folders
        cef-download  Download CEF, see curl-dir config in Gruntfile.js
         cef-extract  Extract CEF zip
        cef-symlinks  Create symlinks for CEF
                node  Download Node.js binaries and setup dependencies
            node-win  Setup Node.js for Windows
            node-mac  Setup Node.js for Mac OSX and extract
          node-clean  Removes Node.js binaries
      create-project  Create Xcode/VisualStudio project
               setup  Alias for "cef", "node", "create-project" tasks.
              jshint  Validate files with JSHint. *
                copy  Copy files. *
               clean  Clean files and folders. *
                curl  Download files from the internet via grunt. *
            curl-dir  Download collections of files from the internet via
                      grunt. *
             default  Alias for "setup", "build" tasks.

Look at all that goodness! So many Grunt commands at your disposal all ready to go.

The first thing you need to do is run the cef command, which will download Chromium Embedded Framework and prep it for your build. Type `grunt cef` in your terminal and you should see something like this:

$ grunt cef
Running "cef" task

Running "cef-download" task
Downloading This may take a while...

Running "curl-dir:cef-mac" (curl-dir) task
Files "downloads/" created.

Running "cef-clean" task

Running "cef-extract" task

Running "cef-symlinks" task

Done, without errors.

Now do the same thing for node.js by typeing `grunt node` in the terminal:

$ grunt node
Running "node" task
Downloading node-v0.8.20-darwin-x86.tar.gz. This may take a while...

Running "curl-dir:node-mac" (curl-dir) task
Files "downloads/node-v0.8.20-darwin-x86.tar.gz" created.

Running "node-clean" task

Running "node-mac" task

Done, without errors.

Now you are ready to do a full-build. To do that (yup, you guessed it) type `grunt full-build`. It will take a bit of time, and will end with a warning:

Warning: Unable to read "installer/mac/staging/" file (Error code: ENOENT). Use --force to continue.

Don’t worry about the warning, if you made it that far you made a full build! You can check out your newly-built app in the brackets-shell/installer/(mac or win, depending on your OS)/staging folder. Run it and make sure it loads your index.html file by default now. (it shouldn’t prompt you to locate an index.html file, it should just open and run the one from your html application)

Let’s customize!

You probably noticed your new application’s name was “brackets” and that your icon for the app was the brackets logo. You don’t want that, so let’s change the name of your app to “Awesome”.

There are a couple of places you will need to change to get your app name changed:

1. Gruntfile.js – change the build name

Screen Shot 2013-06-24 at 3.07.07 PM

2. appshell/config.h – Change the app-name for windows and osx

Screen Shot 2013-06-24 at 3.06.13 PM

3. appshell_config.gypi – Change the app-name as well

Screen Shot 2013-08-01 at 12.46.32 PM

Now just type `grunt full-build` at the terminal and it will create a build with your app and name the app “awesome”

What’s Next?

For basic HTML apps that you just need a shell for, this might be all you need. But this is only the beginning of what you can do with brackets-shell. Over the next few weeks I will be posting new tutorials showing how you can:

  • Use built-in JavaScript functions that map to window functions (Drag, Quit, Create popups)
  • Map custom JavaScript functions to C++ functions that alter the window in other ways
  • Add features like Tray icons in windows, and stay on top of all other windows all the time
  • Use node for advanced tasks and call those tasks from JavaScript in the browser window

As always, let me know if you have any comments or questions!

I am a full-stack web developer that is passionate about start-ups.


  1. Matt / June 25th, 2013 23:43


    Great post. I discovered desktop applications powered by HTML/JS a few weeks ago and I must say that Brackets Shell is probably the most straightforward building tool, I’m looking forward to read new posts about its other features.
    However, I’m stuck in the full build step, apparently grunt wont run the build-num task, which blocks the whole build process.
    Do you have some clue ?

  2. Clint Berry / June 26th, 2013 2:57

    @matt – Hmmm, maybe your wwwRepo location isn’t right, but you should run grunt with -v which gives you a lot more output so you can see what is wrong. I’ll email you.

  3. Moin / June 26th, 2013 12:36

    Amazing post Clint!
    I did not know we can create native desktop apps with HTML5 before. WOW…..
    Thank you.

  4. Jasdeep Khalsa / June 26th, 2013 12:59

    Great post Clint :) This sounds awfully similar to the AppJS project: which, when I tinkered with it, was very straightforward to use! Any ideas how the Brackets Shell differs?

  5. Ryan Mueller / June 26th, 2013 13:48

    Looking forward to the additional posts. This is such a new project there isn’t much documented yet. Any suggestions for additional reading?

  6. Que / June 26th, 2013 17:00

    Thanks Clint your this wonderful post, looking forward to more posts. Keep up the good work.

  7. Saeed / June 26th, 2013 20:38

    Awersome! Can the next tutorials be published today?

  8. Mathew Porter / June 26th, 2013 21:14

    Great informative post, I havent come across Brackets before,just got it on download now to get started.

  9. Juan David / June 27th, 2013 3:51


    I give it a try and after becoming happy because my app works I discovered that Brackets doesn’t support HTML5 Audio . Maybe you could add this thing to the bad about brackets list, in your Desktop Packagers post. Thank you in advance.

  10. Neville / June 27th, 2013 11:39

    Good article and definitely an interesting topic. How do see this compares with App.js and Node-Webkit

  11. Simon / June 27th, 2013 15:22

    Adobe…..meh! Nice article, however I would find it difficult to replace Sublime (which does everything I need) with any code editor Adobe produces considering their track record.

  12. Clint Berry / June 27th, 2013 17:08

    @Neville – App.js seems to be dead. No active development in a long while. node-webkit is active and backed by intel, but we had issues with running it on windows. Plus it doesn’t come with such an easy way to bundle the app into an exe and isntaller.

  13. Clint Berry / June 27th, 2013 17:09

    @Juan – I agree, that is lame! I will fork it and see if I can add it. I don’t know why there would be licensing issues, I will look more into it. I will definitely add this to my list of negatives in the other post.

  14. Clint Berry / June 27th, 2013 17:10

    @Saeed – What do you want to hear about next? More on windows dev, OSX customizations, node.js integration?

  15. Clint Berry / June 27th, 2013 17:12

    @Jasdeep – App.js is basically dead and uses a very old CEF. It wasn’t able to run our angular app at all. It also doesn’t come with the awesome Grunt scripts brackets-shell does.

  16. Neville / June 28th, 2013 12:00

    @Clint, thanks for the info, I didn’t realize App.js was dead, its a pity. Another new .exe packager is however it doesn’t include Chromium. In fact for my use case I’d don”t want Chromium so Nexe maybe suitable, when it matures a bit.

  17. Clint Berry / June 28th, 2013 16:57

    @Neville – That looks awesome, but no windows support yet :-(

  18. Saeed / June 28th, 2013 17:11

    It will by nice if the next tutorial covered the fundamentals . I mean how does it even work?, what are the underling technologies is been utilized here?, a bit on chromium, cef. That should set the scene to cover topics like “Map custom JavaScript functions to C++ functions …”.
    The first commit on the project is good reference point.

  19. Minkyu Lee / July 6th, 2013 14:54

    Very good article for me! I’m really expecting next articles earlier.

  20. Josh / July 17th, 2013 1:57

    Great article! Is anyone else having a hard time with the “config.json” warning durring the full build? The warning is causing the build to be aborted

  21. Clint Berry / July 18th, 2013 4:00

    @Josh – They just updated brackets-shell a few days ago. I will run through my instructions and make sure they still work.

  22. Lev / July 22nd, 2013 18:19

    Thank you for the article Clint!
    Are there any ways to use methods from .DLL files? I mean how to perform low-level tasks in Brackets Shell using JavaScript?

  23. Cohoman / July 27th, 2013 15:11

    Thanks for the great info. I followed your instructions, but I’m getting the following error when I try to build my own web app with Brackets Shell:

    Running "build-branch" task
    >> /Users/dave/Desktop/Bracket_Shell/dev-tools/my-app
    >> git status
    >> chdir(): No such file or directory
    >> Error code: 127
    >> chdir(): No such file or directory

    I’m running on a Mac, and from this message it seems grunt is looking for a directory to cd into which I don’t have defined? Any ideas?

  24. Cohoman / July 27th, 2013 17:14

    Clint, in your instructions you state, “Make your app folder a child of the shell folder”, but when I do that I get an error message when running grunt that indicates my app folder should be in the same parent folder as the brackets-shell folder (so, a sibling). When I make that adjustment and run ‘grunt full-build -v’, I know get the following error message:

    Running "build-num" task
    >> /Users/dave/Desktop/Bracket_Shell/dev-tools/my-app
    >> git log --format=%h
    >> fatal: bad default revision 'HEAD'
    >> Error code: 128
    >> fatal: bad default revision 'HEAD'
    Warning: Task "build-num" failed. Use --force to continue.

    The scripts aborts after getting this message. Am I missing something?


  25. Peter Flynn / July 28th, 2013 4:28

    @Clint – I spotted two potential errors in the instructions:

    1. “Make your app folder a child of the shell folder” should be “Make your app folder a sibling of the shell folder”
    2. If a project isn’t using Git already, doing `git init` isn’t enough. You also have to make at least one commit — otherwise `git log` won’t work and the “build-num” part of the build will fail.

  26. Peter Flynn / July 29th, 2013 8:15

    One other correction: if you edit the app name (as in the “Let’s Customize” section), you also have to update appshell_config.gypi — otherwise the “stage-mac” task will fail.

  27. Clint Berry / August 1st, 2013 18:35

    @cohoman – Sorry about that, it should be a sibling, not a child. I am updating the post. The error you are getting is from your app folder not being in a Git repo. Run git init in that folder and it should work.

  28. Clint Berry / August 1st, 2013 18:43

    @Peter – Thanks!

  29. Richard / August 10th, 2013 5:53

    Great tutorial! Works like a dream. I notice that even after we make the application name edits at the end of your post, when we run the app that is created after grunt full-build, the application is still referred to as “Brackets” in the menu system (e.g. “Quit Brackets”). Do you know if there is a quick fix for this?

  30. Laurent / August 14th, 2013 12:50

    Awesome article!
    1/ Is it by running “grunt full-build” that you generate the windows & osx installer?
    2/ How do you manage databases in such app? Can you get mongodb support or something? Of course without requiring the user to install anything else…
    3/ Appjs from what I can see on their github doesn’t seem to be dead, why are you saying that?

  31. Clint Berry / August 19th, 2013 18:00

    @Laurent- 1) `grunt installer` does the trick. 2) You can’t bundle a database at this time, but you can use local storage in the browser 3) The only commit on appJS in the last 5 months has been a pull request 12 days ago. It has pretty much died in comparison to the others, but maybe he will pick it back up again.

  32. Paul / August 21st, 2013 23:00

    Is there a reason you didn’t just use AIR to build your HTML app and deliver it natively? Just curious as I am looking to build a desktop app and AIR looks a bit easier.

  33. Kailash / September 3rd, 2013 5:19

    Thanks a lot for the detailed explanation @Clint. Was wondering if the brackets-shell supports the new HTML5 notifications api!!


  34. Alexandre / September 16th, 2013 6:47

    tried using an example with a tag – when I start the first step that is to rename the www folder and choose another html file, I simply get a black screen.
    Is the video tag supported at all?

  35. Stakshi / October 1st, 2013 6:51

    Thanks for post… waiting for subsequesnt articles. esp. nodejs one… need to use it… can you share some link from where i can start basic reading for that…

  36. Max / October 5th, 2013 19:33

    Hi Clint,
    interesting post, thanks. However, after trying it out myself, I realized that I misunderstood the aim of that method. I was under the impression that the result would be one .exe file that contains everything, including the content. So that this one file is everything, the client needs to run the app. What I got was an executable that still needs the html etc. content inside a subfolder.
    So two questions:
    1. did I do someting wrong and it is actually possible to build one completely self-contained .exe (including contant) this way?
    2. is there a way to modify your approach so that the result is said self-contained .exe? Or are there other ways to achieve this that you know of? (And I am not taking about an installer that just unpacks the files a real standalone executable)
    Thanks a lot for your effort!

  37. Clint Berry / October 8th, 2013 9:23

    @max – On windows, no, I don’t know of a way to make it all self contained into one file. On Mac it is like that. Sorry, Max.

  38. Clint Berry / October 8th, 2013 9:25

    Node article is coming soon. To start I will probably do a post with the simple way to add node libraries, but is also not necessarily the way brackets-shell intended. I say that because adding node libraries through the client is a bit of a pain for your own custom project. Give me another 2 weeks to get that post out, but it will come.

  39. Jarno Le Conté / October 13th, 2013 10:10

    A really nice article, because nobody else mentioned Brackets-Shell as native desktop app framework. I used node-webkit before but create cross-platform builds look easier with Brackets-Shell. I was wondering if it is the intention of Brackets-Shell that you can use it for your own projects?

    I’m also interested in using node.js in Brackets. I can’t find out by myself how they are using node in the brackets app itself. It looks they calling node functions only in the extensions, right? I should have to wait for your new post about node.js.

  40. Florian / October 17th, 2013 17:15

    @Clint : First, thanks for this tuto (and also for the others articles. Each one is really interesting and well written !)
    A question, i don’t really understand one point –> Is it possible to create an a folder with a .exe and its ressources that can be launched without any installation?

    An other one (not really a question in fact but i’ll appreciate if you could give me your point of view)
    First i tried the TideSDK approach, but the fact is that I want to structurate the js code with Angular Fwk. And I read some articles that seems to indicate that their were some issues … Do you think the 1.4 version will fix these issues ?

    Thks a lot !

  41. Antonio / October 20th, 2013 9:36

    Great post. Nos im evaluating technologies for our project, and this is one of my favourites, bit i have a question: is there any way to protect the html and js source code?

    Thanks in advance, and congratulations, it’s a really good blog!

  42. Félicien FRANCOIS / November 11th, 2013 13:13

    Great post but I have tested brackets-shell by my self and I get disapointed :
    1) Brackets-shell is NOT easy to build. Yes, grunt is a good tool but brackets-shell build is a kludge with so many reasons to fail (especially under windows). Additionally it take a long time to build and tweaking is not documented so we have to try some magic and see that it don’t work after 20 minutes of build.
    2) There is very few documentation. Very few for building. None for tweaking, None for shell API.
    3) It seems it has not been designed to use for a third party software (the build tutorial describe how to build Brackets and not brackets-shell, there is no doc and it evolve in the Brackets way (ex: menubar in black since a few weeks)).
    4) It is buggy. I tried it under Windows 8 and Mac OS X and I quickly found various bugs (refresh issues, css support, javascript events not triggering, …), in an sample app but also with Brackets app itself.
    5) It is backed by Adobe. For me it is a bad point. Their are not known for their open source contribution … but they are known to build white elephants.

    Then I tested Node-webkit, which is backed by Intel and which have almost the same activity than Brackets-shell.
    - It is very simple to use and to build (unlike you said but maybe it has changed since)
    - It allow to package the code (unlike Brackets on windows)
    - It has a better performance (thanks to the use of the same thread & memory space to run Node & DOM JS)
    - It is well documented (including API)
    - It is tweakable enough for me
    - For now I havn’t found any bugs

  43. Kevin / November 12th, 2013 19:56

    Was browsing for an easy way to build native apps with HTML; TideSDK is really the easiest it can get, but not that actively developed and has some glitches. This article taught me about CEF, the Brackets Sprint text editor (which is awesome), and Brackets shell. Excited about using all of them. Thanks a lot, nice post!

  44. Clint Berry / November 13th, 2013 0:07

    @Félicien: Yes, node-webkit has come a long way, and I will re-visit. For me, however, the build process was amazing for Brackets shell. I’m sorry it didn’t work as well for you. At the time of writing, node-webkit didn’t have a simple single command to bundle an app. I will have to investigate further on this, since you make it sound easy. Lastly, we have run our angular app on every version of windows after XP and haven’t found any bugs in brackets shell. It is just a Chromium browser, so if you are seeing bugs, there is something else at play there. We did, however have many bugs with creating additional windows in node-webkit, but no issues in brackets-shell. Again, I will have to go checkout if those issues have been resolved.

  45. Chris / November 14th, 2013 12:22

    How difficult is it to test the app using brackets?

  46. Carl Bourne / December 1st, 2013 1:37

    Hi Clint, Is there any progress with the Node article?

    I’m trying to get this working in a custom brackets-shell app but have been tearing my hair out trying to get it working. As @Félicien mentions Node-Webkit seems to be much easier to work with, although I had problems using custom modules that used native code. Had to re-compile using the node-webkit compiler. Do you know if this is this the case for brackets-shell?

    The brackets-shell build process is nice though and works well from within the WebStorm IDE.



  47. Ram / December 3rd, 2013 16:08

    Hi Clint,

    Great post!

    I have unique requirement, I would like to use the Bracket Shell and load the application from the server and use HTML5 manifest to cache the application assets locally on to the disk, there by reducing the overhead of downloading the application assets (JS, CSS, images, fonts, etc) every single time. Whenever my application changes, I would update my Manifest file, which could trigger re-downloading the entire application assets.

    The reason for opting for such option is to sneak-in WebKit + V8 in to a financial enterprise where still IE8 is the default browser (the only formally approved browser :( ) and its hard to convince and educate users that Google Chrome is the most advanced browser and provides performance and if not all, the most complete HTML5 features.


  48. daslicht / December 12th, 2013 18:09

    “Backed by Adobe – A corporate sponsor doesn’t guarantee that the project will be around forever, but it is more promising than not having one

    LOLOLol That was the best Joke of the Year !

    ADOBE has stoppend so many Projects, Flex, Fireworks.. Whats next ?

  49. Clint Berry / December 12th, 2013 19:49

    @daslicht – True, it doesn’t guarantee it, but I still think it is better than some guy in his basement… take AppJS for instance. It is now gone. Every big company has projects they created and abandoned, but I am feeling good about the activity on Brackets.

  50. Joke, Meepeek / January 5th, 2014 7:48

    This is a very interesting project. Thanks for your review.


Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>