Update: node-webkit is now called NW.js and uses io.js and Blink instead of Node.js and WebKit. All other information is still correct.

JavaScript can be run in a browser normally, on a server with Node.js, and on mobile devices with Cordova, but where else can we use JavaScript to program?

Well, plenty other places, but the last big place to write programs is the desktop and today I’m covering writing desktop JavaScript applications with node-webkit.

Skip to the Code

What is node-webkit?

node-webkit is exactly what it says, it’s the combination of Node.js and Webkit.

Actually, node-webkit is the combination of Node.js and Chromium, the open source core of Chrome. Webkit is used to render HTML and CSS into webpages, so you can think of it as a view engine.

NodeWebkit is a hard to place project. Unlike Cordova, NodeWebkit is not a framework, and unlike Node.js it doesn’t just run JavaScript. It is a runtime environment, like Node.js, but, unlike Node.js, it’s also a browser, which means you can run JavaScript, HTML, and CSS.

NodeWebkit’s primary aim is allow developers to write desktop applications with pure web technology. The reason it comes with Node.js is to get access to the file system, the processor, and anything else usually outside the very limited sandbox of a browser. Chromium is used to render a GUI for a user to interact with.

With node-webkit you can get all the low level system access of a C++ program, but with the ease of programming of a website.

How is it Different From Other Desktop Systems

I haven’t written many desktop applications, but the ones I have written were using C++ / Qt and ActionScript / Adobe AIR, so I will be comparing node-webkit to those.

Adobe AIR is a runtime environment for running compiled ActionScript code. It run on the desktop and mobile devices. Adobe AIR is to the desktop and mobile platforms what Flash is to the web. Simply put, it’s a program for running byte code compiled ActionScript.

Qt is a C++ framework for writing GUI driven desktop applications. It includes a widget toolkit of commonly used GUI elements for quickly building applications. While Qt can run in almost any environment, I have most often seen it run on the desktop. Unlike Adobe AIR, Qt applications are compiled into machine code.

While Qt has GUI elements built in, Adobe AIR doesn’t. Some would argue this, saying Adobe AIR has Flex, but you don’t have to use Flex to use Adobe AIR.

On the other hand, node-webkit does have a GUI system built in. This is kinda a cheat as it’s GUI system is the standard HTML5 GUI tags available in every browser. This includes buttons, check boxes, radio buttons and even new elements, like the range slider.

Advantages and Disadvantages

Unlike Qt, node-webkit is not compiled. It’s more like Adobe AIR. This means node-webkit will be slower than a Qt driven C++ application. It will probably also be slower than Adobe AIR applications, as node-webkit applications are powered by non compiled JavaScript.

But anything you write in Qt or AIR you should be able to write in node-webkit more quickly, with fewer issues, and without the need learn a new language.

Let’s Finally Get to Coding

Similar to Node applications, NodeWebkit applications start with a package.json file.

{
"name": "nw-demo",
"main": "index.html"
"window": {
"toolbar": false,
"frame": true,
"width": 800,
"height": 500,
"position": "mouse",
"min_width": 400,
"min_height": 200,
"max_width": 800,
"max_height": 800
}
}

Name and main are normally part of the Node package.json, but window isn’t. Being that NodeWebkit has a window we can control how it works.

I always specify toolbar:false, this means that your application won’t show the browser’s toolbar. Here is an example with toolbar:true.

Making Desktop JavaScript Apps with NodeWebkit - Toolbar True

And again with toolbar:false.

Making Desktop JavaScript Apps with NodeWebkit - Toolbar False

As you can tell most times you won’t want to have a toolbar.

Just like Cordova, node-webkit works best with a single page application approach. This means we need to create an HTML page that will be displayed as the primary page for the application.

I tend to call my main page index.html. It needs to be located in the same directory as the package.json.

<!DOCTYPE html>
<html>

<head>
<title>node-webkit Test</title>
</head>

<body>

</body>

</html>

Now you just have to build out this HTML file as if it’s running a single page web application. You can import JavaScript files with tags and CSS files with tags just like you would from a normal web application. Better yet you can also import Node.js modules with the require function, just like you would in Node.

<!DOCTYPE html>
<html>

<head>
<title>node-webkit Test</title>
<link href="my/css/file.css" type="text/css" rel="stylesheet" />
</head>

<body>

<script src="my/js/file.js"></script>

<script>
var myNodeModule = require('myNodeModule');
</script>

</body>

</html>

Compiling Code

To compile the code you just have to zip the package.json file and all your project files together.

You then should rename the file to have an .nw extension.

myProject.zip
Becomes
myProject.nw

After this node-webkit can run the application just as it would any other desktop application.