Stop fighting Node.js in the enterprise

5 Comments March 19, 2014


In 1995 there were around 40 million people on the internet, but by 2011 there were almost 4.5 billion. The average computer has gotten so ridiculously fast that my phone has more processing power than the server that hosted my first website. Internet connections have improved so much that buying a physical copy of any media just seems silly. Web services now exist to commoditize almost any functionality a website needs. Elastic computing has made scaling almost trivial. With each of those changes, web development has shifted. With each shift, the basic client-side technologies had to adapt, and we’re now at a point where forcing most application functionality into the browser isn't just a possibility, it’s a necessity if you want to keep up with the competition. Over the past 2 decades JavaScript along with its frameworks, tools, and patterns have evolved and are is still evolving. Somewhere along the way JavaScript morphed from a sacrilegious language used only when absolutely necessary, to a fully vibrant first-class citizen of web development.

With the rise of Node.js in recent years, there appears to be a lot of resistance to using JavaScript on the server and even more resistance to Node.js itself. In my opinion, this resistance is based on varying degrees of misunderstandings, misinformation, and an archaic view of JavaScript in general. In this post, I intend to cover all of the major arguments against using Node.js in the enterprise.

But you’re just some JavaScript developer…

I am NOT a JavaScript developer. I am a software developer. JavaScript is not my language of choice, but I use it where I find it appropriate, just like every other language I know. I’m perfectly comfortable playing in any of the major SQL variants, writing C/C++ code when .NET gets in my way, or even using some inline assembly just for fun with new CPU instructions. I’ve dabbled in Objective C and Java for native mobile apps, and I think I might be the only person I know that actually enjoys writing regular expressions. It’s important to understand that I’m not some JavaScript evangelist trying to sell something. I’m just a developer who sees value in Node.js based on almost 2 decades of experience building web applications.

But why would I implement some other server…

First, Node.js is NOT a server. That is a one of the fundamental misunderstandings that prevents adoption in the enterprise. I use Node.js nearly every day, and rarely do I use it as a server. Running Node.js without a script provides a prompt where arbitrary JavaScript can be executed. That is very handy for executing snippets, but in actuality, that prompt can serve as another shell on the system. Thinking of Node.js as a shell, and scripts as shell scripts provides a better explanation of what Node.js actually is. Think of Node.js scripts more like bash or PowerShell scripts. If one of those scripts spin up a web server, then that script is a web server. We can debate the merits of spinning up servers in a script shortly. What makes Node.js so much better than other shell alternatives is NPM. The package manager allows me to pull in packages that do almost anything. Those modules include data access libraries, compilers, servers, and everything else.

Second, Node.js is NOT limited to HTTP/S. Node.js has support for TCP and UDP. Focusing on HTTP/S takes away from the raw power of Node.js. People have built some crazy things like DNS and SMTP servers. This is important because I don’t recall anyone implementing a DNS server in IIS. This level of flexibility creates so many additional options that the current enterprise server selections just cannot match.

Third, Node.js IS a platform with plugins. Out of the box, Node.js contains listeners for HTTP, but it does not contain a real server. It’s on the developer to write their own server or use NPM to pull one in. Everything else in Node.js works the same way. The minimalistic API provided by Node.js provides all the tools to build almost anything. The huge package repository provides implementations of almost anything. Anything that’s necessary is a few NPM packages and a few lines of JavaScript away.

But JavaScript isn’t a real language like [insert language] here…

Most of these arguments against Node.js start to turn into holy wars that just aren’t productive. I’m not interested in hearing people push new languages or spew vitriol about a random language. I’m interested in getting my job done. Most intelligent arguments around the use of JavaScript tend to speak to the capabilities of the language. That is all that I intend to speak to here.

This isn’t 1995, and JavaScript has grown up. The ECMA 6 specification includes classes, interfaces, and all of the goodies usually associated with popular object-oriented languages. Those features are coming, but in the meantime, TypeScript provides those features with compile-time checks. Even without those features, JavaScript developers have thrived on prototypical inheritance. Additionally, JavaScript developers are just as creative as any other language’s developers. JavaScript supports unit testing, dependency injection, error handling, and all of the other features that enterprises actually care about. Sure JavaScript has its oddities just like every other language. That doesn’t make it any less capable of getting the job done.

That said, conversations about Go or Dart or any other new language or platform are outside the scope of this post. Sure Go is neat, but it’s not JavaScript, and JavaScript is what’s running on the client. Dart’s not running in IE, and I still have to support that. Part of the argument for Node.js is to use an existing set of resources without the need to learn any additional languages. With that in mind, any new language is already out. To further that, JavaScript is the only well-known and hiring-friendly language that can be used to increase parity between the server and client while reducing overall dependencies of the project.

But JavaScript is still script…

Scripts have been used on the server since they started handing out content. PHP and ASP are both scripts. With ASP.NET MVC, Razor views are looking a lot more like those old ASP scripts. The web is trending toward scripts on the server. Why can’t JavaScript join the party?

Because you can’t write elegant JavaScript code…

This is totally subjective. Ugly code can be written in any language. People may complain about JavaScript’s style, but they aren’t holding obfuscated code contests for JavaScript. Most of the time this argument is based on a lack of consistency between developers or a lack of knowledge of JavaScript patterns. There are standard coding conventions for Java and C#. C and C++ almost force conventions just to make them usable. JavaScript on the other hand has no general authority dictating how it should be written. The advent of massive browser-based application has not only shed light on that problem, but produced a series of patterns and practices to make enterprise JavaScript code much more elegant.

Because you don’t get compile-time checks…

JavaScript does not have a compiler so those checks don’t happen. JavaScript does however have static code analysis tools like jshint and jslint as well as unit testing frameworks like Jasmine and QUnit. What more do you actually need? Static code analysis and unit testing are much better means of validating your code, and if used properly, can serve the same process. If the JavaScript would have failed a compile-time test based on syntax, the static code analysis should catch that. If the JavaScript would have failed a compile-time test based on errors in the code, the unit test should catch that. If compiler output is still that important, then TypeScript’s compiler should provide anything else a developer demands.

Because you shouldn’t do anything really complicated with it…

While the internet at large would disprove this argument immediately, why not take a look at an individual project. Cloud9 is an IDE written in JavaScript with the back-end running Node.js. It has all the features a developer would expect from a modern IDE including code completion, deployment automation, code folding, command windows, and source control integration. I’m not exactly sure where the bar for complicated is set, but writing an entire IDE seems complicated enough.

But JavaScript doesn’t belong on the server…

First of all, JavaScript has been running on the server since Netscape released SSJS for NES (Netscape Enterprise Server) back in 1994. From there, AOL acquired Netscape and started the Sun-Netscape alliance turning NES into Sun Java System Web Server which was later renamed to the Oracle iPlanet Web Server when Oracle acquired Sun. On the Microsoft side of the fence, JScript was registered as an Active Scripting Engine which means that it’s been available for server-side scripting in ASP since IIS 3 was released. JScript.NET was released in 2002 for ASP.NET developers. That means JavaScript has been a continuously supported server language on the Microsoft stack since 1997.

Just because JavaScript has been available for server development since browsers became popular, that does not mean that it necessarily should be used. The arguments against its use are varied, but they tend to fall into generic arguments against JavaScript, V8, or Node.js.

Because JavaScript is slow…

Most of these arguments are comparative to other languages. Performance comparisons to .NET or Java seem immediately hypocritical due to V8’s similar issues with just-in-time compilation, garbage collection, and marshalling. In any of these cases, the argument is no longer about the language, but instead is focused on the virtual machine that’s actually executing. Historically JavaScript has been slow, but Google has made significant improvements here with V8. The introduction of Crankshaft into V8 used adaptive compilation to significantly improve startup and computational performance. Crankshaft uses a base compiler to compile the script to machine code that is reasonably optimized. A runtime profiler monitors the application to find hot spots just like a developer would do if they noticed a performance issue. An optimizing compiler is then used on the hot spot code to further optimize just that code. If the underlying algorithms that determine how to optimize the code were wrong, the optimizing compiler will simply revert back to the base optimizations and find something else to optimize. Last month, changes were made to the compiler to offload compilation from the main thread onto a background thread. Prior to this change, the main thread compiled the script into machine code just before execution. Offloading most of the compilation to another thread allows the main thread to focus on execution. Along the way there have been various other enhancements to garbage collection, optimization algorithms, etc. With processors getting faster and V8 getting more efficient, over time any performance issue with JavaScript becomes negligible. From my perspective, V8’s performance has been better than adequate for enterprise applications for years. That said, if you believe that there is a performance issue specific to your project’s needs, test it. Metrics are the only viable argument here.

Because of some single-threaded issue…

This argument is complicated because it is nowhere near as technically simple to argue as it sounds. Under the covers, Node.js manages its own threads for I/O for each process. There are so many weird issues here that it becomes difficult to find a place to start without saying something incorrect. Let’s take that sentence piece by piece.

“Under the covers,” Node.js is an open-source application written in C++. Because Node.js is written as regular program, it can do anything else a program can do. The fact that Node.js can run scripts is irrelevant to the underlying architecture of Node.js itself.

“Node.js manages its own threads for I/O” by using libuv for operations involving the network, file system, etc. libuv essentially creates a thread pool for I/O that varies in size based on platform. The V8 event loop is a separate thread that processes events in the queue. Those events map to a JavaScript function to execute with the event data. This is how asynchronous I/O is handled by Node.js.

There is a single V8 event loop “for each process.” That said, Node.js provides a clustering API that allows a master Node.js process to spawn child processes. The clustering API can also be used for cross-process communication between master and child processes. Each process would then receive its own V8 event loop and therefore its own JavaScript thread. This is how “traditional” multi-threading can be achieved in Node.js.

Even with all of those caveats it gets more complicated because Node.js is extensible and modules can include native code. Native code can generate threads. There are already modules that generate background and worker threads to perform their own functionality, and several modules that provide threading as their primary purpose.

With all of that said, it doesn’t matter. The fundamental problem with these arguments is that Node.js as a platform is designed around asynchronous I/O and not threading. Those concepts are similar, but completely different. In essence, it doesn’t matter if Node.js is multithreaded. Multiple threads are useful to complete multiple long-running tasks simultaneously. The problem is that long-running tasks in modern web applications are not really long-running, but instead they are blocked by long-running calls external to the actual executing thread. Most of the time spent during a normal request to a modern web application is spent waiting for a database call, REST API request, or file operation to complete. Asynchronous I/O takes a different approach by issuing an external call and moving on to the next available operation, or in the case of a web server, the next available request. When the call completes, it gets thrown into the event loop just like anything else. When it makes it to the front of the queue, the function to run upon call completion is executed without the actual thread ever waiting. This allows a single thread to handle many more request than a traditional multithreaded approach. Additionally the memory required for a closure-based context is much less than a traditional reusable pooled thread approach. The asynchronous I/O approach is so compelling that the async and await keywords were introduced into C# as part of .NET 4.5 and asynchronous controllers were introduced in ASP.NET MVC 4.

Because JavaScript can’t scale…

This argument usually comes from a lack of understanding of asynchronous I/O. Node.js can scale as much as necessary with the previously mentioned asynchronous I/O model, clustering to scale across CPU cores, and cloud-based elastic computing. For example, check out Uber’s results when they transitioned to Node.js from a LAMP stack.

But this whole JavaScript thing is just a fad…

JavaScript was initially released in 1995 as LiveScript. That’s almost 2 decades of JavaScript for developers. Comparatively JDK 1.0 for Java 1 was released in January of 1996 and .NET 1.0 was released in February of 2002. Beyond that fact that developers have been developing for JavaScript longer than Java or C#, there are few other reasons that JavaScript will survive the test of time.

What is going to replace it? Dart? I find it much easier to believe that all of the JavaScript replacements are fads rather than JavaScript. Chrome may have the market share to implement something like Dart, but enterprises still have their IE browser requirements. It’s much more likely that Dart gets relegated to sidelines in favor of the guaranteed browser support of JavaScript. As long as JavaScript remains on the client, the potential to solve the impedance mismatch with client-server communications will keep JavaScript alive and kicking on the server.

What other language can actually run everywhere? Java tried. .NET and Mono tried. JavaScript has always and will continue to win this battle in the browser. It’s only natural that it take over the server as well.

I honestly cannot come up with a reason why JavaScript would slow down, much less fade away.

But there aren’t any serious implementations out there…

Microsoft and Amazon both support Node.js with Microsoft being a major contributor to Node.js since 2011. Azure Web Sites and AWS Beanstalk both provide simple methods for deploying Node.js applications into the cloud. There is no way to know what amazing things are coming, but there are several serious projects already out there.

Doctape is using Node.js for API requests as well as also media streaming and conversion. Scrollback uses Node.js for their real-time messaging infrastructure. FrisB converted over to Node.js for scalability improvements for their WebRTC infrastructure. Twelephone is using Node.js for their Sykpe-alternative. Voxer uses Node.js for their messaging infrastructure. PINT’s entire CMS system is built on Node.js. Fidelizoo uses Node.js for their digital loyalty card management system. Transloadit uses Node.js to handle millions of file upload and conversion requests per month. ZingChart uses Node.js for server-based chart rendering. Caliper uses Node.js for trace requests for their analytics platform. Klout is also built on Node.js.

Fine, but nobody I’ve actually heard of is using it…

There are actually plenty of major players already using Node.js. eBay is using Node.js for the ql.io platform. MySpace is now a Node.js application. The mobile version of the New York Times is a Node.js application. LinkedIn uses Node.js for their mobile application stack. PayPal is moving their entire application platform from Java to Node.js. PayPal, by the way, is at the time of this post the 17th most visited site in America and the 41st most visited site in the world.

But… But… But…

My final point is simple. It doesn’t really matter if you resist Node.js for enterprise development because it is already in the enterprise. It has already amassed a huge following. Web developers already know JavaScript. V8 has already proven its performance. Node.js has already proven its scalability.

Just check out this graph showing monthly contributors to open source projects by language. With the Java and C# community stagnating, JavaScript has been growing consistently for almost a decade. That graph appears to show that the active open-source JavaScript community has surpassed their C# and Java counterparts combined.

Check out these statistics showing the growth of Node.js websites over the last 6 months as well as the traffic those sites are handling. Sure that number is a very small percentage, but growing by 241% in 1 year is impressive either way.

Node.js is only going to get bigger. It is not a fad. Yes it has faults, but it is ready for primetime right now. My next posts will cover some of those faults 


5 Comments

  • Gravatar Image
    Den March 20, 2014 10:17 AM

    It does sound like a JS evangelist talk. Still, it's interesting to read about the silver-bullet of the year. Is there a beta of some Node.js killer on the horizon already? Maybe... Meanwhile there might be an option for people who want to use something like Node.js but with a proper programming language: http://blogs.msdn.com/b/webdev/archive/2014/02/18/introducing-asp-net-project-helios.aspx

  • Gravatar Image
    Anonymous March 25, 2014 11:40 AM

    It can't be denied that one can use Node.js to do interesting things. Even things at scale. But it speaks volumes that one needs to evangelise Node.js at all.

    We are at a time in which there are many different languages and that these languages are increasing as time go by: the choice for developers is far and wide. Sure more users might be using node.js and that trend may continue but it is a very very long way behind php. Secondly the idea that there are lots of open source contributions to Node.js means that it is widely adopted or useful is questionable. Much of the "open source" contribution is at best experiments that stop and at worst poor unmaintained code. It is also true that there is a lot of good open source. But we need to be honest!

    For enterprises: there might be a ton of Javascript/Node.js developers but many of them are primarily low volume website developers. I don't deride Javascript and Node.js indeed I think that it is overstated that these are "easy" scripting languages .. one needs to be pretty good at them to get the most out of them. The kind of "goodness" I am talking about I can see in more Scala people who come for Job interviews than Javascript people.

    Do we need just one language for front and back? This is also arguable. The main argument being a single developer can do both web front end and heavy server back end. Well I am sorry, but there are actually very developers like that. It is more than the language itself that is at play here.

  • Gravatar Image
    Anonymous May 1, 2014 10:19 PM

    It is possible to write enterprise backend code with JavaScript but sometimes it can be a total pain in the ass. Seriously.

    JavaScript has been designed and implemented to boost websites with small scripts, therefore it is lacking any good pattern to maintain complex code. Of course, that's not what it was designed for. And I am not talking about the small JavaScript patterns to organize your code (like module pattern, pseudo constructor pattern and so on) - I am talking about the real stuff like inheritance, extending existing classes, defining and implementing interfaces and so on. It just hurts to be trapped to only work with those constrained primitive JavaScript objects.

    Another thing is the event driven nature of JavaScript. People "love" it. Go ahead and implement your most complex backend function with JavaScript - the one with tons of I/O. Believe me you are going to shoot yourself after the first 4 callbacks because you will end up in the famous callback hell - UNLESS you back yourself up with some additional extra library to make your code stay readable (like async.js, bluebird.js). This is your one and only evidence that the language itself is just not the right tool for complex stuff as it needs backup to even stay maintainable.

    I think that node.js is one kickass tool for small backend operations, prototyping, small games and such - but definitely not the right language for heavy enterprise backends. However, I'm still very excited about how EcmaScript will evolve over the next few years.

  • Gravatar Image
    Brian August 4, 2014 3:54 AM

    "using a proper programming language", "it is a very long way behind php", "JavaScript has been designed and implemented to boost websites with small scripts, therefore it is lacking any good pattern to maintain complex code".

    These sorts of comments are the ones that help me weed out applicants. Like the author, I've written everything from assembly to HTML. I don't just mean "tried it once or twice either". I've written or supported major applications, with millions of users a day, in Java, .NET, PHP, and node.js.

    I've come to find that Javascript allows you to be more elegant than ANY other language (excepting Scala), used in the enterprise today, specifically because it's so "unstructured" in it's design. Key here is how everything is an object... and not in the way that everything in Java is an object. In Java, you have primitive types... but not in Javascript.

    The build/test/deploy tools that have been developed for the javascript platform over the last 5 years have been transformative to ALL programming languages. I work for an enterprise that employs over 15k programmers... most of which are Java programmers. Even so, many of them take a look at tools like npm and grunt, and our social rooms fill up with comments about how great it would be if Maven/etc... were that simple to configure and run/manage build and dependencies.

    Specifically, the commonJs "module" pattern, drives several other standard patterns in Javascript, that share names with their OO patterned cousins, but are far more elegant in their execution. Personally, I love the way the decorator, singleton patterns are built in js compared to how they are built in any other language. They're far easier to build, and they can be built dynamically, anytime after initial program bootstrap, and they will retroactively lend support into objects already in memory without having to ever reference the object already in memory.

    As far as "node.js is a long way behind php"... shows a misunderstanding of both Javascript AND PHP. In recent updates to the PHP language, as well as PHP peripherals... php has driven to follow the example set by node and javascript ecosystems. Composer was modeled off of npm, at a time when PEAR and Pyrus just weren't cutting it. PHP was battling to be accepted in the enterprise also, against mostly the same space that .NET holds, and until 5.4 and 5.5, PHP didn't even have many of the enterprise object oriented capabilities needed that Javascript (being capable of conversion to .NET IL) was already providing to the .NET framework (both in browser, server, and other .NET platforms).

    PHP has an enormous amount of documented performance issues, and is not even a contender in most language comparison performance tests.

    Both PHP and Java are starting to adopt some of the functional oriented capabilities of javascript. That's not because they're trying to attract js developers... it's because that type of scope inheritance or dynamic assignment has some serious advantages.

    Due to the power of client hardware... developers are starting to build serious video games using javascript and OpenGL, and they rival their C++ counterparts. Mozilla, in 2012, cross compiled the c/c++ Unreal Engine 4 into javascript, and ran video games built on the engine in the browser at near native speeds.

    I have a soft spot in my heart for PHP, because it's the first serious language I started programming with, and at the time I learned it, I had to study Java OO patterns to learn PHP patterns because there just wasn't any material out there yet. But when it comes down to it today, when given any project, I rarely see PHP as the PRIMARY project language, preferring to reserve it's use as an api solution.... which I typically prefer python, Scala, or node.js first, due to the scalability and performance gains all of them have over PHP.

    The last comment concerning Javascript not being considered "a proper language". Javascript is very fluid and requires creativity, yet is easy to learn how to do it poorly. Because of that "blank canvas", you aren't "building on rails" like you are with many languages in the Enterprise today, where there are common practices for "do this thing". But.. you're restricted to doing it the OO way whereas in Javascript, you can do it the OO way, or any other way you want.

    Now, why I would say I'm not a node platform evangelist.. when given the option to write something with both front and backend components, I typically don't choose node over Scala, or even python and sometimes PHP... depending on how much control I have or need to have of the deployment environment. At the moment though, that's because it's highly likely to be able to run Scala/Java/python/PHP on just about any server you might deploy to... whereas node is not likely to exist on a server unless I put it there.

  • Gravatar Image
    KobiKobi August 8, 2014 1:21 PM

    I actually LOVE regular expressions!!! They are a light saber for some of the most interesting real life problems out there.

Have a Comment?