In the last few months, I’ve been playing around with two tools to help bridge the gap between the web and native desktop applications. There are two main tools that come to mind – nw.js (formerly known as Node Webkit) and Electron (formerly known as Atom Shell).
This post focuses on using both, the differences between the two, and focusing on issues that I’ve encountered.
Outline:
- Getting started – package.json
- Native Menus (application menu)
- Shell execution (child processes)
- Packaging / run
- Icons
- Performance
Nw.js
Getting started
Nw.js and Electron share a lot of the same steps for getting started. The only real difference between the two is how they are run, and how they handle the node process internally.
With Nw.js, your app is bundled together. With Electron, the application is set up differently – with the main node process the handle running the browser process, and the rendering process, which handles all things from the browser (the event loop).
To get running, download the nw.js app or the electron app. Both of these applications look at your package.json
file to get running by looking at the main
attribute.
Bootstrapping
For nw.js, the main
attribute should specify which html file to start loading when your application launched. With Electron, your main
attribute should specify a JavaScript file to be run.
You also specify attributes about the nw.js window that runs via the window
attribute, things like toolbar
, width
, and height
, notably.
With Electron, the JS file that you specify will launch the browser window and specify other attributes like width, height, and other window attributes.
For convenience sake, I also created a node run script to execute the Nw.js app with my current folder. To run the node-webkit app, you simply type npm run nwjs
. I also included a livereload script to watch my www
folder to live reload my changes in the nw.js app.
Here’s a quick look at the package.json
file used to bootstrap nw.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Here’s a quick look at the package.json
file used to bootstrap Electron:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Additionally for Electron, my main.js
file looks like the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
|
Native Menus
Electron
Due to the way electron is split up into two processes, the main process (that handles native menus) and the browser process (mainly your app), menus are mainly available to be set on the main process.
If you want your app to change your application menus, you’ll need to use the ipc
module electron provides to get a message out to the main process to update the menus.
Other than that, the menu system is super easy if you wish to use static menus.
Nw.js
It’s dead simple. Since it’s all one bundled process, just call the set menu, and you’re good. It’s easy to set short cuts and modify the menus.
Shell execution
In nw.js, you’re good to go when it comes to making external shell calls.
When it comes to electron, make sure you spawn your child processes with the pipe
stdio option. Without that option, you may run into some errors (due to the fact electron doesnt have a stdout it manages easily).
Packaging / running
It’s really easy on both platforms. Just set up your package.json/index.html/main.js file and run the appropriate command.
I don’t have a lot of experience with nw.js, so I cant speak to the packaging process.
For electron, to run I like to use electron-prebuilt to run my www
files as an app, using electron-packager to package into an .app
file, and electron-builder to create installers (dmg/setup.exe).
Icons
To get custom icons for your app files for Mac, you need an .icns
file that bundles up all your icons in all the formats/sizes for your dock icon, your cmd+tab icon, and your running icon.
I used this as a walkthrough.
I first started with a size of 1024x1024 pixels, then used the following commands:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Then just run:
1
|
|
You should now have your app with icons ready to go.
Performance
I didn’t see a lot of major performance bumps from using either platform. It’s JavaScript after all.
Closing words
Most of all, have fun with developing with these tools! They’re open source and free, so when you get a chance, share some knowledge, post an issue, respond to an issue, or even submit a PR.
We’re all in this together.