Differences between Narwhal and Node.js
I would just add RingoJS to the mix. It is a Rhino-based CommonJS system, but comparing to Narwhal it is much more mature (its primary author has been developing its predecessor Helma for years) and by following both Git repository's development, RingoJS seems to be much more active. Development of Narwhal seems to be kind of slow these days.
If you're using either Node.js or Narwhal, only use packages and modules that advertise compatibility with your respective engine. There are presently many nuances to writing applications, packages, and modules that work on both engines. Kris Zyp from Dojo has put quite a bit of effort into making his packages work on both systems and I cannot think of anyone else.
Narwhal's input and output modules are blocking, much like the standard libraries for Python, Ruby, Perl, C, Java, and so on.
There is, however, a class of applications that cannot be effectively written with blocking I/O, like games that maintain their state in the memory of the server and stateful communication with numerous clients. Only experimentation can reveal whether threads or event loops perform better for individual applications. But, it is furthermore difficult and perilous to write "evented" applications in most programming languages and library ecosystems because the benefits of using non-blocking I/O can be quickly obviated by making use of any blocking I/O, and blocking I/O is frequently hidden in the layers of architecture, even as low as the operating system interface. Node.js is exciting, because it is creating an ecosystem with strictly asynchronous I/O, which makes it the first system in which this class of application is reasonably easy to write.
Proponents like Douglas Crockford and Mark Miller argue that asynchronous event loop programming is the way most applications should be written because it is easier to reason about data flow, concurrency, and security in these systems and to blindly compose such subsystems without compromising correctness or integrity.
However, if you want to take advantage of JavaScript as a language, but do not want to buy into the additional complexity of event-loop programming, Narwhal is designed to work on both JavaScriptCore, the fast JavaScript engine behind Safari, and also on Rhino. Using Rhino gives you access to Google App Engine. Narwhal was designed to give you flexibility of your JavaScript engine, but it did not account for Node.js's I/O model. Narwhal is also used extensively by the 280 North software ecosystem, for build tools and servers for Cappuccino Objective-J applications, like Jake and Jack.
Both Node.js and Narwhal can be used for general applications and web servers. Node.js is particularly well-suited for network clients and servers. Narwhal is particularly well suited for Unix-style programs and JSGI, CGI-like web servers, and is designed to run JSGI applications on a variety of web servers without alteration.
Writing applications that work on both Narwhal and Node.js is difficult but possible. Writing "packages" that work for Narwhal and Node.js is possible, but it must be done deliberately. If a package does not advertise that it's been designed and tested on both Narwhal and Node.js, you can bet it will only work on one or the other.
io: Modules that do not make use of I/O subsystems, like parsers, formatters, encoders, and decoders, are particularly well suited for code sharing between both Narwhal and Node.js.
packages: There are differences in the way packages are laid out for NPM (Node Package Manager) and Tusk (Narwhal's package manager). They both use package.json, but "dependencies" have different meanings on each. There is an upcoming patch for Narwhal that allows it to tolerate this inconsistency. When packages are installed in Narwhal, they all share the same module name-space, like Ruby. With NPM, each package has a subtree of the module name space by the same name as the package.
modules: Node.js and Narwhal both provide varying extensions to the CommonJS module specification.
Node.js provides additional free variables like
__dirname
.Node.js allows the exports object to be reassigned with
module.exports = x
.Narwhal provides
require.once(id, scope)
for executing a module once (regardless of whether it has been previously loaded) with extra free variables in scope (these are sometimes erroneously called "globals").Node.js does not provide the CommonJS
module.path
for the file name of the current module.Narwhal and Node.js provide incompatible systems for extending the module loader to handle alternate languages for modules, like CoffeeScript and Objective-J.
If you prefer Narhwal's synchronous style, you can also use my Common Node package which allows you to run synchronous Narwhal, RingoJS and other CommonJS compatible packages as well as JSGI web applications on Node.js.