Node-Webkit Development

I’m in the process of porting RiddleMeThis from Realbasic (er Xojo) to Node-Webkit (henceforth nw). The latest version of nw allows full menu customization, which means you can produce pretty decently behaved applications with it, and they have the advantage of launching almost instantly and being able to run the same codebase everywhere (including online and, using something like PhoneGap, on mobile). It has the potential to be cross-platform nirvana.

Now, there are IDEs for nw, but I’m not a big fan of IDEs in general, and I doubt that I’m going to be converted to them any time soon. In the meantime, I’ve been able to knock together applications using handwritten everything pretty damn fast (as fast as with Realbasic, for example, albeit with many of the usual UI issues of web applications).

Here’s my magic sauce — a single shell script that I simply put in a project directory and double-click to perform a build:

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo "$DIR"
cd "$DIR"
zip app.nw *.html package.json *.png *.js *.css *.map
mv app.nw ../
cp nw.icns ../
cp info.plist ../
open ../

What this shell script does is set the working directory to the project directory, zip together the source files and name the archive app.nw, and then move that, the icon, and the (modified) info.plist into the right place (assuming the node-webkit app is in the parent directory), and launch it. This basically takes maybe 2s before my app is running in front of me.

info.plist is simply copied from the basic nw app, and modified so that the application name and version are what I want to appear in the about box and menubar.

This is how I make sure the standard menus are present (on Mac builds):

var gui = require('nw.gui'),
    menubar = new gui.Menu({ type: 'menubar' });
if(process.platform === 'darwin'){
gui.Window.get().menu = menubar;

And finally, to enable easy debugging:

    var debugItem = new gui.MenuItem({ label: 'Dev' }),
        debugMenu = new gui.Menu(),
    debugItem.submenu = debugMenu;
    menuItem = new gui.MenuItem({ label: "Open Debugger" });
    debugMenu.append(menuItem); = function(){

So with a few code snippets you get a Mac menubar (where appropriate), a Dev menu (if dev is truthy) and a single double-click to package and build your application in the blink of an eye. You can build your application with whatever Javascript / HTML / CSS combination suits you best.

Obviously, you don’t get a real “native” UI (but the next best thing is a web UI, since people expect to deal with web applications on every platform), and this isn’t going to be a great way to deliver performant applications that do heavy lifting (e.g. image processing), but it’s very easy to orchestrate command-line tools, and of course the chrome engine offers a ridiculous amount of functionality out of the box.

I should mention that Xojo is actually quite capable of producing decent Cocoa applications these days. (It sure took a while.) But its performance is nowhere near nw in practical terms. For example, C3D Buddy is able to load thousands of PNGs in the blink of an eye; the equivalent Xojo application is torpid. Now if I were doing heavy lifting with Javascript, perhaps it would tilt Xojo’s way, but it’s hard to think of just how heavy the lifting would need to get.

Realbasic and Visual Basic

More than anyone except Andrew Barry, I am responsible for the creation of Realbasic. (This doesn’t reflect particularly well on me, it just means that Andrew pays, or paid, more attention to my whining than most random people.)

In the mid-90s, Andrew and I had both been involved in software development across multiple platforms for some years, and both of us were annoyed by glaring flaws in most development tools. I had gone to work for Andersen Consulting and been forced to develop a very ambitious multimedia project using Visual Basic 3, a development tool I found both admirable and horrible in pretty much equal parts. It was obviously inspired by HyperCard, but good in ways that HyperCard was bad (it created native UIs) and bad in way that HyperCard was good (it was horribly unstable, the language reeked).

Andrew and I would often shoot the breeze about dev tools and at some point I opined that what the Mac really needed was something like Visual Basic that didn’t suck. So Andrew created CrossBasic which became RealBasic. Anyone even casually acquainted with the two products will know that Realbasic owes more, architecturally, to MacApp and Java than Visual Basic. E.g. from the beginning there were “folderitems” which strongly resemble the object wrappers Apple’s frameworks use for filesystem objects. Similarly, all visible controls are subclasses of Canvas, which is the base graphical class in Java. Indeed, CrossBasic originally allowed you to compile programs to the JVM. Worst of all, in Visual Basic prior to .NET you essentially use simple variable types except when doing file i/o. In Realbasic you define your own classes and subclasses (including being able to subclass internal classes seamlessly). All of this was part of Realbasic 1.0.

Why bring this up now?

Well, it’s a long time down the road. Andrew left Real software after finishing Realbasic 2 (I think it was 2.1.2 at the time, which was for a long time the “golden” version of Realbasic). A few months ago, I answered a question of Stackoverflow about “which languages supported nice language feature X” and mused in my response that not only did Realbasic support it but that it supported many, many nice language features you don’t expect in a “BASIC”. I then got critical feedback based on Realbasic’s having started life as a “clone” of Visual Basic.

So I’m setting the record straight. Realbasic was never a “clone” of Visual Basic. It wasn’t an inferior copy, but a superior re-imagining. Just as Visual Basic stole ideas liberally from HyperCard while being dramatically superior in many ways, Realbasic stole ideas liberally from Visual Basic while being dramatically superior in almost every way. (E.g. it never put developers through DLL hell, even under Windows.)