A few months ago I wrote a blog post titled Electron vs nwjs which has gathered quite a bit of traffic. I have spent the past five months building sizable apps with both projects (to be clear: different apps) and I feel as though I have some excellent clarity into the things I both like and dislike about Electron and nwjs — as well as my current approach to building apps in each.

Note: everything that follows is completely anecdotal. I’m just some guy who builds software and rants about it on The Internet; trust my advice and experience at your own peril.

OSS Activity

As I mentioned in my prior post, Electron is still my preferred project. One of the things I really like about Electron is the pace at which new releases are coming — there have been 10 releases since the end of September! The project is quite stable despite that pace, and bugs appear to get fixed quickly. The dev team is also very active on the GitHub issues.

By comparison, nwjs only has two releases since I wrote my original post. Some rather important (IMO) bugs have yet to be fixed in v0.12.x.

Release activity may not always be a sign for “the better choice”, but considering that GitHub maintains Electron I think it’s a solid reason to lean that direction right now.

The nwjs docs on GitHub also seem to be fairly outdated. They regularly refer to “node-webkit”, which hasn’t been the project’s name in nearly a year.

Winner: Electron

“Securing” Source Code

At a high level, Electron and nwjs are exactly the same thing. They both enable you to package a web application (plus some Node.js back-end stuff) into a standalone desktop application. There are some nuances between the two with regards to how “context” is derived, the general APIs that govern windows, menus, etc… but for the most part, the only significant difference between the two projects boils down to one feature: the ability (or lack thereof) to “secure” your source code.

nwjs offers the ability to protect JavaScript source code with a v8 snapshot. Electron does not.

I have already gotten into an argument with the Electron contributors about this topic. In my opinion, this single feature is the only reason why developers will choose nwjs rather than Electron… yet they seem pretty disinterested in pursuing the idea.

Their argument has merit – the v8 snapshot isn’t true source code security, it’s just well-obfuscated code — and it comes with a sizable performance hit. But if the only alternative is to leave source code completely clear, developers would much rather choose the illusion of security for proprietary applications. I think it’s a no-brainer to add that feature; they disagree. For now.

Winner: nwjs

Build Process: Grunt

For my own projects I frequently use Grunt to do of the local build things — it’s really easy to setup, and it really helps create “production” versions of your applications. Both Electron and nwjs have very helpful Grunt packages available on npm and GitHub.

The ones I use for Electron:

grunt-exec : Running command-line tasks is incredibly useful

: Running command-line tasks is incredibly useful grunt-contrib-uglify and grunt-scram : Remember how Electron doesn’t have a v8 snapshot or any mechanism to secure your source code? A combination of UglifyJS and scrambling the results will at least deter most people from spying on your souce code. (THIS IS NOT SECURITY!)

and : Remember how Electron doesn’t have a v8 snapshot or any mechanism to secure your source code? A combination of UglifyJS and scrambling the results will at least deter most people from spying on your souce code. (THIS IS NOT SECURITY!) grunt-contrib-copy : Helpful for copying files/folders around the file system

: Helpful for copying files/folders around the file system grunt-string-replace : Helpful for updating build numbers and other things

: Helpful for updating build numbers and other things grunt-electron: The real meat of the build process. Specify the desired name/version/platform you need for a production app. Even includes the .asar compression for your app folder.

The ones I use for nwjs:

grunt-exec : Running command-line tasks is incredibly useful (same as I did in Electron). Specifically,

: Running command-line tasks is incredibly useful (same as I did in Electron). Specifically, grunt-contrib-copy : Helpful for copying files/folders around the file system (same as I did in Electron)

: Helpful for copying files/folders around the file system (same as I did in Electron) grunt-contrib-concat : Helpful for many things, but most notably if you need to concatenate many JS files before you “secure” them in a v8 snapshot

: Helpful for many things, but most notably if you need to concatenate many JS files before you “secure” them in a v8 snapshot grunt-nw-builder: Similar to “grunt-electron” in that it produces the desired name/version/platform for a production build.

For example, to create the v8 snapshot you might do the following:

grunt.initConfig({ exec : { nwjc : { cwd : 'build/nwjc', cmd : 'nwjc app.js app.bin' } }, concat : { nwjc : { dest : 'build/nwjc/app.js', src : [ 'app/js/fileA.js', 'app/js/fileB.js', 'app/js/fileC.js' ] } }, nwjs : { options : { platforms : [ 'win32', 'win64', 'osx64' ], buildDir : 'build/platforms', version : '0.12.3', //macIcns : '', //winIco : '' }, src : [ 'build/production/**/*' ] } }); grunt.loadNpmTasks('grunt-exec'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-nw-builder'); grunt.registerTask('default', [ 'concat', 'exec', 'nwjs' ]);

The last step here (“nwjs” target) assumes some other things are in my build/production folder, but you get the idea.

My Grunt setup for Electron is nearly identical, minus some nuances in things needed for the individual projects.

Winner: tie

Startup Time

While I didn’t try to specifically time the startup process in both of my apps, I will say that Electron started noticeably faster on OSX and Windows — both locally during development, as well as my production builds.

Oddly enough, my Electron app is considerably more complex than my nwjs app. The nwjs app did use a v8 snapshot (which has a known performance hit), but even running the app locally without the v8 snapshot it seems much slower to startup.

Winner: Electron

What is your Experience?

Remember: I’m just some guy who builds software and rants about it on The Internet. Your mileage may vary significantly with these projects, but barring the need to “secure” your source code I would choose Electron every time.

If you have built apps with either of these projects I would love to hear more about your thoughts and experiences!