JavaScript conquers the server

Node.js, Jaxer, EJScript, RingoJS, and AppengineJS combine the familiarity of JavaScript, low overhead, blazing speed, and unique twists

In 1996 when no one believed in Apple and AOL was voted most likely to succeed, Netscape took its shiny, new JavaScript language from the browser and stuck it in the Netscape Enterprise HTTP server. That was probably the first moment that someone tried to make JavaScript the lingua franca for back-office servers, but it wasn't the last. After Netscape dissolved into Mozilla, new stacks with JavaScript have come and gone as the true believers try again and again.

Now some 15 years later, JavaScript on the server is back in vogue. The buzz from the latest round of believers is that JavaScript is the "new Ruby," for all of the same reasons that Netscape began the trend. Using the same code for the client and the server makes life easier for everyone -- you never know when you'll need to move a routine from one to the other. I can't tell you how many times I've tried to make sure that the Java version of the SHA256 hash algorithm running on the server produced the same output as the JavaScript version running on the client.

[ Also on InfoWorld: 13 open source development projects making waves in the enterprlse. See "Open source programming tools on the rise." | Keep up on key application development insights with the Fatal Exception blog and Developer World newsletter. ]

But some things are different this time. Many of the earlier efforts were built around perfectly nice JavaScript engines like Rhino that offered perfectly acceptable performance. Now we have a number of new JavaScript engines such as Google's V8, which is much faster and uses many of the just-in-time compilation ideas that sustained Java's virtual machines over the years. Suddenly JavaScript is speedy enough that people think of using it for its velocity, not its convenience. It's entirely possible that all of the hard work on the browser engines is making JavaScript the fastest dynamic language and one of the best choices for server-side programming.

To understand the latest burst of enthusiasm, I spent some time installing a few of the more interesting JavaScript servers and building a few basic websites. The tools were all intriguing, thoroughly fun, and oozing -- the software equivalent of a fresh, clean coat of latex paint. This newness cut both ways, though, because some of the documentation was sketchy and many of the demonstrations were not much more complicated than spitting out "hello world."

I enjoyed the challenge and stimulation of rethinking everything I know about the server, but I still found myself hesitant to push these new ideas too far or too fast. These servers are fresh from the lab and made for experimenting, not building an application for Grandma to check the interest on her CDs. The ideal project for a corporation might be a temporary website for a one- or two-day event that would come and go in a flash. For now, enjoy creating something new and fun with them, not betting your business.

JavaScript servers: Node.js The hottest star is undeniably Node.js, a simple package that is attracting the kind of attention that leads people to roll out the term "fanboy." Blogs such as How to Node are filled with hints and suggestions as people try to figure out just how far they can push the tool. There's already been a conference devoted to the project, and people are using the word "node" as a verb that means to write Node.js code. Will the language still be around next winter for us to make puns about "bad code in the node"? I'm sure the ideas will still be here because they're powerful, but the names may morph into something else because there's plenty of reinvention in this space.

The most powerful idea is that Node.js is light, whereas alternatives such as Java are heavier. The secret of the tool's success seems to lie in one factoid often repeated by Node.js lovers: a Java server uses 2MB of RAM just to create a thread. As the standard Java Servlet container creates one thread for each request, it's clear that a fairly hefty server with, say, 8GB of free RAM can handle only 8,000 people. Of course the threads often use more memory, which further cuts into the overhead and positions 8,000 as an upper limit.

Threads were supposed to be lightweight ways for a processor to juggle the workload, and they were certainly successful back when people were satisfied with handling several thousand simultaneous users. But when people started counting up the costs of the overhead for bigger and bigger websites, some started wondering if there was a better way.

Node.js is one good solution. It uses only one thread for your server and everything runs within it. When the requests come flying in, Node.js takes them one at a time and hands them to the single function that was specified when the server is invoked. If you thought that a Java Server Page, a Java Servlet, or a PHP file was a lightweight way of building a website, you'll be impressed with the efficiency of this:

What? If you're going to point out that a JSP or PHP file may be as simple as the words "hello world," stop right there. You have to think beneath the surface and remember everything that the Java Servlet container or PHP server does for you. You may just write "hello world" in a JSP, but Java will burn 2MB of RAM creating a thread that supports the code that will eventually output the thread "hello world." The JSP might seem simple, but it's not.

Node.js does very little except grab the incoming request, call the function website, and marshal the results out the door. This single-mindedness lets it juggle all of the requests hammering at the port and dispatch them quickly.

I've seen standard-issue desktop machines easily handle thousands of requests more or less simultaneously. The data goes in and out like lightning because everything is handled in RAM and probably in the cache. Simple websites are surprisingly efficient.

But it's important to recognize that some of this lightning speed comes from leaving out other features. Running everything in one thread means everything can back up if that thread gets overloaded. All of the work that Java spends on putting clean, fresh sheets on the bed really pays off if one thread takes a long time to finish.

To make this happen, I created a simple server that takes a value "n" and adds up all of the numbers between 1 and n. This, by the way, is a purely CPU-bound operation that should use only two registers. It can't get hung up by waiting for RAM or the file system. The server was just as fast as before. I had to feed my underpowered desktop (1.83GHz Intel Core Duo) numbers like n=90000000 before it seemed to pause at all. That's a 9 with seven 0s after it. The answer had 16 digits in it.

When I fed fat numbers to the server, I found that all of the other requests would get in line behind it. When the workload is short, Node.js seems to be multitasking because it gets done with everything so quickly. But if you find an item that weighs down the server, you can lock up everything in a queue behind it.

Fear not. If this happens, Node.js lovers will blame you, not the machine. Your job as a programmer is to anticipate any delays, such as a request for a distant Web service. Then you break your code into two functions, just as AJAX programmers often do on the client. When the data is returned, Node.js will invoke the callback function. In the meantime, it will handle other requests.

In the right hands connected to a right-thinking mind, the results can be staggeringly efficient. When the programmer spends a few minutes and separates the work done before and after a delay, there's no need for the machine to tie up RAM to hold the state in the thread just so it will be ready when the data finally shows up from the database or the distant server or even the file system. It was undeniably easier for the programmer to let the computer keep all of the state, but it's much more efficient this way. Just as businesses try desperately to avoid tying up capital in inventory, a programmer's job is to think like a factory boss, treat RAM as capital, and avoid consuming any of it.

This mind-set may seem like a burden to programmers who are used to letting the compilers think about such things, but JavaScript programmers are accustomed to working with callback functions because that's how the browser's sandbox is configured. This kind of segmentation is second nature to them, and that's why they're so in love.

I think Node.js will quickly grow beyond doing simple experiments and begin to handle semiserious but lightweight tasks such as online polls and simple message passing between users. If the server workload is simple and short-lived, Node.js is a good solution. The tools are solid, at least as experimental, bleeding-edge code goes, and I expect that skilled JavaScript programmers will be able to write simple chains of callbacks that do some amazing things with low-rent iron. Will bigger responsibilities follow? I suppose that's possible, but for now this is enough for everyone to digest.

JavaScript servers: Jaxer Another, completely different option for the JavaScript lover is Jaxer, a nice tool from Aptana, the folks who make a great, Eclipse-based IDE for Ruby and PHP. Aptana's tool for server-side Java is very different from Node.js because it's aimed more at making life easier for the programmer rather than the server. Jaxer handles all the complexity of message passing behind the scenes, so writing server-side code is like writing client code.

Writing a server-side script for Jaxer is just like writing one for a Web page. The difference is that you sneak the attribute runat='server' into the script tag. That's it. Everything else is akin to building a JavaScript-enabled Web page. Whenever you call a function with the special runat attribute, it will be executed on the server, not in the browser. Jaxer handles the chores of bundling the parameters into an AJAX call. One little attribute controls where the code runs, and Jaxer handles all of the message passing and invocations.

The freedom can be a bit unnerving for old hands at JavaScript programming who've spent years thinking they were programming only the client. Now you can write to the database or access distant files by merely inserting the runat attribute.

I found it pretty easy to build Web pages using the technique. Anyone who is new to AJAX will discover it's much more convenient to let Jaxer handle all of the background work of bundling and unbundling the data. It's all mostly automatic and even simpler to use than some of the AJAX libraries such as jQuery.

It's not clear how much support Jaxer is enjoying these days. The server used to be bundled with Aptana's other offerings, but now it's left alone in a corner. My guess is that many people don't need that much help handling AJAX calls now that libraries like jQuery simplify the process.

The ideal job for Jaxer will be one where most of the work is done on the client but some crucial part must run on the server. It's very easy to make code run on the server, but it's not so easy to write complex server-side code. There are plenty of jobs like this, and the people coding these jobs are the ones that Aptana is targeting when it says you can write an entire Web application in one file.

JavaScript servers: EJScript Although the idea of using JavaScript on the server sounds simple, there are a surprisingly diverse number of ways to approach it. EJScript is quite different from both Jaxer and Node.js but very similar in structure to classic server designs like Ruby on Rails and Struts. It's built using the pure Model-View-Controller paradigm, so it will be quite familiar to anyone who's created websites using the popular Ruby or Java frameworks.

The basic tool is a command line that can either execute JavaScript or create a Web server. If you want to write your server scripts in JavaScript, the basic shell will do so. If you want to create websites, the tool will build out websites using standard scaffolding for all of the create, update, and delete (CRUD) operations on the data.

The entire process is similar to coding in Java and the various server frameworks in part because EJScript includes a way to define classes and subclasses. This object-oriented structure is a great enhancement for JavaScript if you ask me, but it's going to be different for anyone who's learned JavaScript in the browser. Although most JavaScript programmers know plenty about monkeying around with the prototypes, they may not be as familiar with how Java and other object-oriented languages build out type hierarchies.

EJScript borrows from Ruby on Rails because many parts of the scaffolding are defined by "convention not configuration." The directories are in standard locations, and often the easiest solution is to create a file with the right name. To further differentiate from JavaScript, there's no need for a trailing semicolon if you put the statements on separate lines. The Python and CoffeeScript model is beating out the old C and Pascal worldview.

All of this means that the experience is much closer to writing some combination of Ruby and Java instead of creating JavaScript the way it's practiced by people who chain together jQuery calls for clients. EJScript is a viable product that can be used to build serious websites. The EJScript structure is well suited to compartmentalization, in part because it echoes one of the most common and popular architectures.

This tool is probably best for folks who are well-steeped in both Java and JavaScript. The ideal home may be a project that requires plenty of duplication in the code that runs on the client and the server but a significant amount of structure and business logic on the server.

JavaScript servers: RingoJS Combine the Mozilla Rhino engine with the Java Web server core and you have a mechanism for building a website using JavaScript. RingoJS, like EJScript, embraces the MVC paradigm and echoes many of the common structures used by Java and Ruby programmers. The difference is that the JavaScript is not enhanced with the same object-oriented or syntactical conventions as in EJScript.

The process is similar to building a simple JSP-based site. Perhaps more than many of these other frameworks, RingoJS reflects its Java heritage. There's a fairly complete collection of modules, including ones for profiling and security. Many of these seem similar to their Java counterparts because they're relatively thin layers on top of the Java. The logging, for instance, uses the Simple Logging Facade for Java (SLF4J) to connect with Log4J.

Creating websites with RingoJS was fun but often left me wondering why I shouldn't just code in Java, the common tongue for most of the foundation. If you have enough experience with Java, you'll probably feel the same way. RingoJS isn't meant for people like us. We're probably better off writing code that's closer to the metal.

I think the ideal users will be people who enjoy JavaScript because it's a dynamic language that's a bit more relaxed than Java. RingoJS might be good for a shop where some of the programmers are JavaScript junkies and some are experts in server-side Java. This would allow the two groups to code alongside each other. Those who know JavaScript on the client can now write JavaScript that can leverage all of the power of the Java server stack. The others can write Java.

JavaScript servers: AppengineJS Let's imagine that you admire the stability and flexibility of Google App Engine's Java runtime, and you enjoy the straightforward nomenclature of Google App Engine's Python API, but you have the need to write your code in JavaScript. If you fit in the center of this Venn diagram, then AppengineJS is for you.

Some clever folks have combined the Rhino JavaScript engine written in Java with a thin layer of an API that uses the Python names. It all rests on top of the Google App Engine Java API. The result is similar to what you might write in Java or Python for the Google App Engine, but it uses the JavaScript syntax.

The ideal users will be those who love the Google App Engine model and its support for quick-scaling applications but can't bring themselves to program in either Python or Java. Now you can write directly to the App Engine API with JavaScript.

JavaScript servers: Stability vs. innovationThis review skipped over a number of different engines and approaches, in part because many of them are fading or at least being eclipsed by new projects. One developer referred to CommonJS, an attempt at building a standard server-side API, as "so 2009." This is how quickly things are morphing. The Java and C programmers might say, "That's so 1995," but their old code from 1995 will probably compile and run even when it uses deprecated functions. Such long-term stability is not yet part of the game here because everyone is having much more fun reinventing tomorrow. Many of the most creative developers seem happy to coin an entirely new name, rip out some of the most useful guts from the old projects, then build something that's sort of new and sort of old at the same time.

Some people who watch the changes see a pendulum that may eventually swing back. Tom Robinson, one of the developers who created the Narwhal framework several years ago, feels there will be some retreat from the callback style that's popular with Node.js devotees right now.

"I'm increasingly convinced this asynchronous callback style of programming is too difficult for most developers to manage," Robinson said. "Without extreme discipline it can easily lead to 'callback hell,' with deeply nested callbacks and complex code to implement logic that would be simple on a synchronous platform."

What's next for him? He sees the older framework being rethought and reworked using the best ideas from Node.js. In place of callbacks, he sees ideas like "promises," "co-routines," "actors," and other objects that hang on to the information in the variables for use later. These objects may be easier to juggle than the callbacks.

That may come to pass with the next generation, but for now most of the interest is in Node.js because of its extreme efficiency. The attention focused on the project must be almost embarrassing sometimes. Some people are treating the Node.js creator, Ryan Dahl, like a rock star. One Q&A interview on the product veered into discussions of whether Dahl really thought "Bridget Jones's Diary" was the best film ever. (For the record, he said it was "definitely top 10.")

The speed of experimentation and development is heady and exciting to the open source crowd, but it will probably seem scary to corporate developers who like the long, stable lives of tools from Microsoft or Oracle. Some of these platforms will probably morph three or four times over the next few years, something that won't happen to the good, old JSP standard in the Java world.

I've often found myself wondering how the Java world might steal some of the ideas for Node.js, as they have with so many other projects. Just as Grails and Trails imitated Ruby on Rails, there's no reason why someone can't build a subset of the JSP standard that will run in a single thread.

One of the biggest problems with using any of these tools for projects with a long life is that the new versions are constantly improving and not much energy is invested into maintaining compatibility. The developers are on the barricades running a revolution, not spending too much time worrying about long-term stability and success.

George Moschovitis, one of the developers of AppengineJS, said that all of this means that he wouldn't recommend any of the tools for serious production work because they're "too immature." But he adds quickly, "I would heartily recommend Node.js and others for prototypes and basic enterprise projects." He notes that projects like Harmony, CommonJS, and Node.js may "change this in the midterm."

In other words, these tools work well for basic prototypes. They're quick and relatively stable. If things go well, they may prove to be ready to add bits and pieces of real responsibility to the programs. When that happens, the projects will slow down and the feature sets will begin to freeze as the users start demanding stability and bug fixes over experimentation and innovation.

This article, "JavaScript conquers the server," originally appeared at InfoWorld.com. Follow the latest news in programming and open source at InfoWorld.com. For the latest business technology news, follow InfoWorld.com on Twitter.

Read more about application development in InfoWorld's Application Development Channel.

This story, "JavaScript conquers the server" was originally published by InfoWorld.

What’s wrong? The new clean desk test
Join the discussion
Be the first to comment on this article. Our Commenting Policies