Deploying Hybrid HTML5 Games on the Desktop Using Node-Webkit

By Geoff Blair and Matt Hackett

So you’ve built an awesome game using HTML5. It looks fantastic, runs smoothly, and feels like a high-quality experience, all right in your browser.

What about monetizing your hard work? If you built a mobile game, you can publish on Apple’s App Store or Google Play, via excellent products like Ludei’s CocoonJS and Intel’s open source XDK initiative. These platforms have been around for years, and games built with their help are out in the real world, making money.

However, what if you made a game tailored for desktop? The open web is a place where people expect content to be free, so upfront charges for premium experiences are often rejected by the market. Given that HTML5 games run great in the browser, it seems like it should be easy to make a unique binary just for your game…

Enter node-webkit

We started working on desktop HTML5 games as Lost Decade Games back in 2010, when there were no tools to help developers with this problem. Today developers are fortunate to have a variety of viable options available. There’s one in particular that’s exceptional because it’s been used to publish games on Steam (the premiere digital distribution platform), and that’s node-webkit.

What makes node-webkit so great? It’s cross-platform (creates Windows*, Mac*, and Linux* binaries), open source (based on Chromium and WebKit), and integrated with Node.js (the popular JavaScript platform). We’ve used it, we love it, we highly recommend it, and it can be used for any kind of application, not just games. It’s great, but to support all this awesome, it can take some effort to understand how to use it. Let’s get started!

Your node-webkit package

Think of node-webkit as the Google Chrome browser that you compile to run only your game. Whatever process you use to package your HTML5 application for the open web will likely make a great starting point for your node-webkit app.

Let’s assume you have your application in a folder, with an index.html file and your related assets (JavaScript, CSS, etc). This is where your manifest should live. node-webkit reads the manifest file to determine how to configure your application. This file is stored as package.json at the root of your project. While there are quite a few manifest options available, we’re going to focus on the basic, required properties.

Here’s an example of a simple node-webkit manifest:

    "name": "A Wizard’s Lizard",
    "main": "index.html",
    "version": "1.0.0",
    "nodejs": true,
    "window": {
        "title": "A Wizard’s Lizard",
        "width": 1280,
        "height": 720,
        "toolbar": false,
        "position": "center"

Most of these fields are fairly self-explanatory. “main” refers to the HTML file to load, so if your file isn’t named index.html, you should change this. You’ll also want to make sure to set the name of your application as well as change the window size to match your needs.

For debugging purposes you can set the “toolbar” property to true which allows you to access the excellent Chromium debugging tools. For advanced manifest options, see the node-webkit manifest wiki.


The next step is to wrap your game as a node-webkit package, which is simply a zip file containing your HTML5 files and the node-webkit manifest described above. There are many ways to zip folders, for example Finder on OS X* (find the folder, right click, Compress) or on Windows* the open source project 7-Zip.

Once you have a zip file, simply change the filename to app.nw. For example: -> app.nw

Next, we need to download the latest version of node-webkit from GitHub. There are several different versions to choose from, but as of this writing, v0.10.x is the stable release.

Note: This version ships with Node.js v0.11.13, so if you have native node modules which only work with Node.js v0.10.x you’ll need to use node-webkit v0.8.x instead.

Each of the supported platforms (Mac*, Windows*, and Linux*) are packaged in essentially the same way, but still require their own steps to complete. Let’s walk through each individually.

Deploying on OS X*

After you’ve downloaded and unzipped the OS X* node-webkit files, you’ll have an OS X* .app package. Since these app packages are really just folders, they are easy to edit. Right-click on and select Show Package Contents.

The most important step is to copy your app.nw package into Contents/Resources. You’ll also want to edit Info.plist in order to change the app’s title and other properties to match your application. Lastly, you’ll want to rename the .app file to match your game (e.g. A Wizard’s

That’s it for getting your OS X application up and running. A customized icon can be added by replacing Contents/Resources/nw.icns with your own icons. (We use the excellent Icon Slate app on OS X to create this icon format.) If you want to create a disk image (.dmg) for your application, we highly recommend the DMG Canvas app.

Deploying on Windows*

Windows* deployment is a little more involved but still pretty simple. First make sure to download and unzip the node-webkit files, as mentioned above.

Now copy your app.nw package into the folder containing the nw.exe file. To bundle your package with the node-webkit executable, run the following command from the Windows command line utility:

copy /b nw.exe+mygame.nw mygame.exe

(Replace mygame with your own game’s name e.g. a_wizards_lizard.exe). The resulting .exe file is a combination of the original node-webkit executable and your node-webkit package. At this point, you can launch your game by executing the file. To polish it up, there are many more optional steps.

For quick ‘n dirty distribution, you can zip up the .exe along with some required files and distribute your game that way. The additional required files are:

  • nw.pak
  • ffmpegsumo.dll
  • icudtl.dat
  • libEGL.dll
  • libGLESv2.dll

Note: It’s also possible to create a Windows installer using WixEdit, but that’s out of scope for this article.

You can change the icon of the .exe using a program like Resource Hacker. If you have a Windows .ico file for your game’s icon, you can easily replace the default node-webkit icon.

Deploying on Linux*

Although often overlooked in the games industry, Linux is perhaps the easiest platform to deploy on using node-webkit! Simply unzip the node-webkit files and copy your node-webkit package into the root of the folder.

From the command line, run these commands:

cat nw mygame.nw > mygame chmod +x mygame

(Replace mygame with your own game’s name e.g. a_wizards_lizard). Now you have a Linux executable which can be launched from the command line like so:


For simple distribution, you can zip up the executable with some required files and distribute your game that way. The additional required files are:

  • nw.pak
  • credits.html

Note: credits.html is particularly important to package on Linux, because some of the open source libraries used by node-webkit legally require notices to be distributed alongside the application.


HTML5 games are a natural fit for the web, but web games can be difficult to monetize. Players often expect web games to be free, and many developers don’t want to pollute their gaming experiences with advertising. One solution is to create a native executable via node-webkit, which is an approach proven by games like Game Dev Tycoon and our own game A Wizard’s Lizard.

For an in-depth, technical discussion about node-webkit and its Steam plugin Greenworks, have a listen to our game development podcast Lostcast 69: Greencast. We often discuss HTML5 game development on our YouTube channel and Twitter, so we hope to see you there. Thanks for reading and go start using node-webkit!

About the Authors

Geoff Blair snowboards and games with his cats and fiancée Melissa in northern California. He co-founded Lost Decade Games in 2010 where he now does game design, programming, and business development.

Matt Hackett obsesses about games in LA with his two cats and user researcher wife Andrea. He co-founded Lost Decade Games in 2010 where he now does game design, programming, and artwork.

For more complete information about compiler optimizations, see our Optimization Notice.