I don’t do very much desktop software development these days, and I’ve become increasingly frustrated with Realbasic (now Xojo), so the prospect of forking out $500 for an upgrade that may or may not be usable did not fill me with glee. Furthermore, as the years roll on, there’s more and more functionality tied to the web that desktop-centric development tools struggle to work with.
I was dimly interested in a thread on Hacker News this morning concerning a workflow for developing desktop applications with node. Turns out that the workflow was mostly to do with things like angular and jade, which I’m not especially keen on, and not so much with the actual desktop stuff — the heavy lifting for which is all done by node-webkit. So I started looking into node-webkit.
I like a tool which has you up-and-running in about three paragraphs.
It goes something like this:
Download an appropriate node-webkit binary. (Disappointingly, the Mac version is restricted to 32-bit.)
- Write an index.html file. (The sample “hello world” app calls node inline.)
- Write a package.json file. (The documentation suggests it’s like a “manifest” file, but really it’s more like a configuration file.)
- Zip this stuff into a file into an archive whose name ends in .nw.
- Double-click the archive.
- Voila, your app works.
After working on this for about fifteen minutes, I knocked up a bash script (which I turned into a .command file, allowing me to double-click it in Finder) which does the archiving and then launches the file in one step. (It does leave dead terminal windows lying around, and it doesn’t quit the app if it’s still running. I think I may build an app for building apps if I do much more of this.)
And to build a distributable application you can simply put the archive in the application bundle (on the Mac) renaming it “app.nw” or name the file package.nw and put it in the same directory as the application (for those benighted platforms that don’t have bundles). One minor annoyance is that it’s not clear exactly what needs to be changed in the Info.plist file to fully customize your application.
So what is node-webkit? It’s essentially a version of Chromium that puts node.js alongside the DOM in your web pages, along with a few custom HTML and DOM extensions that let you do things like handle platform-native file requesters).
I should note that it’s a potential security nightmare as it stands. There’s no sandboxing (that’s kind of the point), so deploying an app that loads your banking website and then watches you press keys is totally doable. That said, it’s a desktop app so it can also delete all your files or encrypt them and hold them hostage.
Anyway, I had a lot of fun this evening rewriting a utility application I originally wrote in Realbasic a few years ago. It probably took me about twice as long to write it as it took me to do it in Realbasic. Part of that is I know (or knew) Realbasic very well, and I don’t know node very well. Another part of it is that Realbasic is almost always synchronous while node is almost always asynchronous. Writing code that spelunks a directory tree asynchronously is a lot more complex both conceptually and in practice than doing so in linear fashion, but the payoff is quite impressive — despite running an “interpreted” language, a task that took significant time in Realbasic (loading and displaying hundreds of thumbnails) happens in the blink of an eye.
One of the things that’s especially intriguing about node-webkit is that it gives you control over the browser you normally don’t have (e.g. window placement, file system access) — these are a constant usability sore-point in the project I am currently working on (which is a web app that is replacing a suite of desktop apps). It would be so much easier to get a lot of the things we want to do working smoothly using a hybrid desktop application built on top of something like node-webkit — it’s kind of a lemma of Alan Kay’s observation that anyone who wants to write really good software needs to build hardware — anyone who wants to write really good web apps really needs to build the browser.
The github repo for my project is here. It’s not a very general-purpose application; if you don’t use Cheetah 3D it’s completely useless.