Node.js versus Ruby on Rails

Unlike many in the developer community, I started out toying with Node.js, and then dove into Ruby on Rails via the delightful Rails for Zombies followed by Michael Hartl’s Ruby on Rails Tutorial. The result is an unscientific comparison of (Javascript on) Node.js vs Ruby on Rails.

Node.js is not a framework!

First things first, Node.js is a server bundled with low-level routing and sysadmin capabilities and written to be utilized with Javascript. To even begin this comparison, Node.js requires some friends in the form of Express.js and Mongoose (should MongoDB be your database of choice) to align with Rails, which is written in the Ruby language.

Ruby is like a crotchety old man with a heart of gold

Now that we have that out of the way…next up is the language. Node.js is written completely in Javascript, while Rails is written in Ruby. In learning both, I find pros and cons for each. On the benefits side, Javascript has an easier syntax to pick up quickly, since you probably know some from front-end coding (as opposed to Rails’ :VARIABLE => hash-bangi-ness, the fact that functions don’t require parenthesis, VARIABLE do |iterator|, :: namespace resolution, < class declaration, and @local parameters borrowed from Perl). However, Ruby can be more succinct and does not require a forrest of brackets to work its magic (coffeescript readers out there, calm yourselves…). Additionally, Ruby (and rails) comes packed with extremely useful built-in functions surrounding everything from dates (think syntax like 10.minutes.ago) to "string".squeeze and ['array' 'elements'].include?('array') #true. Yes, Javascript can accomplish all of this, but it requires some know-how and a few custom prototyped methods…or something like _underscore.

100% Javascript Rocks, but is ultimately overrated

With the languages out of the way, we can turn our attention to actually building web applications. Node.js shines because it enables a front-to-back Javascript environment, where in Ruby you’re forced to contend with SQL, Ruby, and Javascript. While seemingly a superior and streamlined experience, after playing around with both, I’d put the value in the ‘overrated’ category. It really isn’t hard to pick up on Ruby once you’ve ready a number of sample programs and a few blog posts. Additionally, with Ruby, you can almost completely forget about callbacks and the nested soup that Javascript brings to the table because of it’s non-blocking architecture (which I do realize is a plus for certain performance gains).

Rails gives you the full package

Putting languages and stacks aside, Node.js + Express.js offers routing along with free-form controllers, views, and helpers. These tools pale in comparison to Rails. To make an analogy, Rails is to Node.js + Express.js what Muji is to American Apparel. Both will get you clothing and home accessories, but American Apparel’s clothing looks kind of wonky, doesn’t always have what you need, tries to be a bit too cool for its britches, and doesn’t always play nice with other items in the store. Muji, on the other hand, has obsessively designed products that were seemingly cut from the very same cloth.

To get back to programming…Rails comes with a fulsome ecosystem from models to views, controllers, to data object models (which are mostly hidden btw), with extremely clear and concise interactions that can only occur with crazily OCD vertical integration. Two examples: url_for and image_tag. url_for is a built-in function that will always provide the url for a given data object, such as @products, and image_tag pulls in the correct image url from the asset pipeline. While the same is possible with Node.js, it would require some heavy module interaction and helpers. Additionally, in rails, you just don’t need to worry about your data models. While Mongoose on Node.js helps, it’s still tough to really feel like you’re fully taking advantage of easy access like the Product.find(params[:id]) that are easily available throughout your Rails application, modules, controllers, and views.

However, it’s important to note here that these integrations do come with a downside.  Often I feel like I’m guessing at the ‘correct’ way to do something, always missing out on the most efficient way.  Additionally, when something goes wrong, it’s quite a bit more difficult to find out why, since Rails will read into specific variable names, like how you can add _path to new_product_path and have it magically turn into a function that returns the appropriate path for the `new` route within the product controller/model. With Node.js, what you see is what you get, and there is very little interpolation.

More people make and improve Rails modules

Next up is the ecosystem. While Node.js has an excellent start with NPM, the dust hasn’t settled on the most popular packages for various needs (the number of contenders is starting to get overwhelming).  I often feel like I’m clodging together a broken vase with superglue.  Rails, on the other hand, has one of the most robust (and free) sources for libraries and tools. I love The Ruby Toolbox, which actually shows you the relative popularity of Rails tools broken out by function. Additionally, as I mentioned before, many modules that would have to be hand-picked in Node.js are integrated by default in Rails. Stuff like database connectivity, concatenation, cache-busting, database migrations, data models, routing, command line sandboxing/tasks, and testing, etc… It even comes preset with a favicon.ico! These may seem like trivialities, but they’re all 100% necessary…and it’s nice not to have to wade through error messages from conflicting Node.js modules that don’t want to talk to each other at 12am. Layered on top of the modules are more tutorials and examples than one can typically find with node.js. Case in point, Railscast‘s 300+ video tutorials. Although, be forewarned, Rails has been around longer and seems to change faster, so many of the tutorials are out-of-date…or in some cases workarounds for features added after the article was written…as a result, it is prudent to use Google’s date selector for articles < 1 year old and start your search with Rails Guide.

Rails includes a jet pack, standard

Finally, assuming you have equivalent frameworks, database, and modules all set up, Node.js just takes much more time to string everything together (again because of the disparity in 3rd party plugins and lack of any inherent structure). In rails, putting together a complete RESTful interface takes one command line input for all of the controllers, views, and database models. rails generate scaffold Post name:string title:string content:text #and you're done
In many cases, it’s 1 minute versus 1 hour (which adds up if you have 4-5 database objects to contend with). It’s not necessarily hard work, but very prone to typos and simply a lot to remember. I don’t see myself always using Rails scaffolds, but for simple prototypes, it’s unlikely there’s a faster alternative.

In Conclusion…

Node.js is a great set of tools that are hip, growing rapidly with a dedicated userbase, (debatably) high performance, easy(er) to pick up, and better than most other web building apps out there. However, it’s really just a talented high school track star to Ruby on Rails’ Olympian. No offense to Node.js, but who would you rather train with? If you can get over the pain (and annoyance!) of learning Ruby, the choice is clear.  Remember, at least for me, the best tools are the ones that help you launch better and faster.

Leave a Comment