How exactly did we end up here?
Anyway, to stick to the point, after the talk someone in the audience asked me the question:
Well (apart from the obvious time constraint involved) this was a fair question — even though I think it was based on the wrong assumption of what “How it all started” referred to. I thought this might have deserved a bit more elaborate answer than the one given, which was something like:
Occupying the browser
I doubt computing’s most essential law needs any explaining to anyone who got this far in reading this article: Moore’s law (oversimplified) states that hardware complexity (and thus, speed) increases in an accelerating fashion. So far this has been generalized in various ways (i.e.: how it really is about “exponential progress in the wake of tiny revolutions & paradigm shifts”), but we are interested in its rawest aspect: explosive growth of brute computing power in an ever-shrinking package.
Serve your script, and eat it too
But it didn’t stick.
Why? Well mostly because it was a serious pain in the bum using it. For one thing — it wasn’t live at at all, the application had to be compiled after the slightest modification.
Helma & Narwhal were one of those projects. Helma — now abandoned (or rather, spun out into Ringo.js) — was running Mozilla’s Java-based JS-engine, Rhino, while Narwhal theoretically supported several different JS-backends. Both of those frameworks found their respective niches — but neither of those found widespread popularity — that could be chalked up for several of their shortcomings, but before we get there, there is one more thing we need to mention: the DOM.
Both Netscape Navigator and Internet Explorer went on to introduce their own (of course, incompatible) APIs for accessing the document object model, which eventually went on to be standardized separately and became the DOM standard. The DOM is supposed to supply the bindings — both language and platform-independent — to the features exposed in a browser (or more broadly, by the environment), and has evolved just as ECMAScript evolved, in standards released by W3C in tandem.
Eventually, besides the DOM several other features and extensions emerged, some of which went on to be standardized and accepted cross-browser, some of which remained confined to a single browser vendor or environment. Such efforts are continuously being worked on as of today (one particular cooperative effort being the Service Worker specification), and are even encouraged, as a means of extending the web and keeping it up to speed with technological advancements.
Whoah, I have sure preached quite extensively about node up to this point (not that I have any particular interest in selling it to anyone), but hopefully I have managed to give a fair preface to:
Why was node.js a big deal?
It just happened to be
in the right time, at the right place.
Even though the idea of asynchronous, non-blocking/evented I/O wasn’t new at all, event-driven web servers were not all that abundant. Event-driven server origins go as far back as 1999, the nascent Flash (no, not that flash) server used this technique — but other server-side solutions using the same paradigm are on quite short order. In fact, (and please correct me if I’m wrong), node.js actually predates the single other relevant solution I could find, the Tornado web server (written in Python) by at least half a year.
Pointed out by Alexandre in the comments — the Nginx server was also event-driven (which actually is mentioned in Ryan’s original presentation, pitching it against Apache’s threaded system), however I would argue that it is much less powerful/flexible for this to count as fair comparison.
Also pointed out by several readers, the Twisted Framework (written also in Python) was an event-driven async networking framework, which well predates node’s release. One could argue whether Twisted fits the argument above or not, but certainly is a valid point — thanks for pitching in!
(Twisted also has extensive interoperability with above mentioned Tornado web server which I think better fits node, but that’s simply a personal opinion.)
Gathering a Common-ity
The arrival of IO.js in early 2015 has further extended and revitalized the community around node.
Contributions soared sky-high as the open-governance model selected by the fork’s authors started to do its magic:
in a few months, the number of active contributors has overtaken that of the early node.js days, and localization teams took the community to new frontiers.
“Okay, okay — node.js breathed new life into server-side programming, it is our savior, a fearless knight in shining armor, yadda-yadda — I get it, sheesh…” — well yes, but it didn’t even stop there!
Extending the chain of command
(Did you know even Photoshop had its own scriptable node.js instance built in?)
A NW era
Node-webkit spurred a whole new class of desktop projects into existence, and after Cloud9 IDE successfully wedded node.js and web technologies in what became a state-of-the-art Integrated Developer Environment, projects like Brackets and ATOM brought the experience to the desktop (while keeping best of both worlds — cross-platform interoperability, extensibility — intact).
Harder, Better, Faster, Stronger
Browsers? Done. Servers? Easy! Mobile? Devoured! Desktop? Done & dusted! Anything else you might want to try?
Well what about IoT?
Well, this idea of the “internet-of-things” is quite popular nowadays, one might say. Smart watches, smart lighting, smart heating, smart houses; internet-connected fridges and washing machines and electric kettles — you name it.
A fiery fox to the rescue
A few years ago no one would have thought a low-power, cost-conscious mobile device based on web technologies would be even possible — and yet Firefox OS has proven that it was not simply possible, but very much feasible by releasing ~15 different Firefox OS-powered devices in about ~30 countries in the last two years.
Actually it is so far from said limits, that Samsung decided on using it on its smartwatch platform, based on the Tizen operating system — while at the same time, approaching Ecma International’s TC39 with the idea of standardizing a mobile-conscious, even more prudent subset of the language to be used on the smallest scales of devices.
— Atwood’s Law by Jeff Atwood
I won’t try to over-explain the law above (it’s pretty self-explanatory, anyway), but I will try to show it in the works in the remaining part of this article.
There is one small problem with this approach. Besides the initial processing requirement, memory space is required to store the AST so that later it could be executed. For most of the applications this should not be a limiting factor, but when we get down to as low as the sub-megabyte memory capacities of microcontrollers, this becomes a one very real restriction.
The original Tessel
Because of this Tessel was designed to be “node-compatible”, which meant it was able to run most of the modules straight out of npm, without much hassle (provided they didn’t have any binary dependencies — but that’s another story).
Now before we march on to review Tessel’s second iteration, I think we should take a little detour back into FirefoxOS-land:
Firefox OS’s twisted twin brother: Jan OS
Jan OS is based on Firefox OS’s open source code (it’s a fork, if you will), and focuses on the hardware and sensors. The same sensors and modules you could buy for hundreds of dollars as addons for your Tessel, here come pre-soldered to a highly compact and power-conscious IT board (that you got for a few tens of bucks, but back then they called it a phone).
With Firefox OS’s (dead-simple) hardware APIs are all right there, by stripping the unneeded cruft and the UI (GAIA) and security/permission mechanics (basically rooting the phone) you get a highly optimized, cellular-network-connected, low-power internet-of-things board. With an ample power supply you could, for example stuck your contraption out in the wild and have it take and upload photos wirelessly for a whole month!
Might I add, there is even support (in both Firefox OS and Jan OS) for the Raspberry Pi? That said, it should soon be fairly apparent why I chose to introduce Jan OS right before we talked about the Tessel 2.
Tessel 2 — hardcore prototyping
The second iteration of Tessel positions itself on the sweet spot of all those hardware mentioned above: It is nearly as powerful as the Raspberry Pi, it is much cheaper than the original Tessel was (less than half the price!), it is just as modular and extensible as the first one was (heck, it even got better with the inclusion of two standard USB ports!) — and last but not least, runs a tiny Linux kernel and io.js, leveraging the full power, speed and ecosystem node/io.js has to offer, while doing away with compatibility issues once and for all!
Well that’s already nice — but the best thing is yet to come — you could use the Tessel 2 to prototype your product, and also to bring it to market — because if you wanted, you could order a bunch of pre-fabricated Tessel 2-s, with integrated module boards and put them right into your final product!
Way ahead of its time:
The keyword here is: compilation.
Look Ma’ — a time machine!
With browser support expanding, these wonders are reaching more and more users on the web every day, bringing high-performance games and even physics simulation into browsers and to the open web.
However, speed is not the only concern. Sometimes size (see above, for the Espruino) is just as important (if not more important).
That is where our tiny script engines make an appearance.
TinyScript — the Davids to your
Mentioned earlier, Lua has been readily and frequently used embedded in other software products to provide extensibility/scripting to its host software. This was partly due to its simplicity and extensibility, but also due to its small code & memory footprint.
(Espruino’s (even Pico’s) hardware, on the other hand, would still prove too slim even for these tiny runtimes.)
Sporting ECMAScript standard compliance and all the bells-and-whistles expected of a modern JS-engine (garbage collector, unicode support, RegEx engine — you name it) these tiny powerhouses are no small feat of engineering. In spite of these being fairly new projects, some has already started incorporating them in their projects: Game engines, for example have frequented Lua for a long time catering for their in-game scripting needs — the new Atomic Game Engine on the other hand uses Duktape.
Duktape has also approached the bare metal in projects like the IoT framework “AllJoyn.js”, while Tilmann Scheller at Samsung evaluated the fitness of the engine for general use in embedded systems (with very promising results).
There is indeed one more thing. Seeing people on all over the web chanting the old slogan (even those who actually read the article above):
it is a disgrace of a language and will surely remain so!”
Hint: Steven Wittens’ previously linked article on ASM.js also has some pointers.
* in fact V8's “Crankshaft” optimizing compiler has similar peculiarities that arise from code size because it chooses to inline functions based on their text-size (and that includes white-space and comments, too!).
To learn more about this, check out Joe McCann’s talk from dotJS 2014!