Node.js Through the Eyes of a Ruby Developer: First Impression

Introduction

Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js' package ecosystem, npm, is the largest ecosystem of open source libraries in the world.

This is exactly what is written on the Node.js' official site and it is precisely where our team of Ruby developers started investigating Node. In our current project we stick to microservices architecture and already have many small web applications implemented on Rails/Sinatra. At some moment it was decided to experiment with Node and we all set to exploring this alternative. Below I will try to share my first impressions about this platform after a month of using it.

The first question we asked ourselves was – "What is Node exactly?" It's not the implementation of a language (JavaScript), not a library or a framework and not a web-server. You can find such definitions as environment and runtime. I came across the following definition on some forum – it's an event-loop with libraries. It doesn't really clarify the matter, does it?

We didn't want to work with Node as with a black box, so we delved a bit deeper into its source code, implementations of its standard library and of libuv library, where all the primitives of asynchrony and nonblocking computations are actually carried out. This explained a lot and it became clear not only how to work with Node, but also what its benefits and drawbacks are.

Then, we started exploring applicable libraries and tools, similar to those which we usually use in Ruby/Rails stack. We weren't interested in Rails clones, such as Nodal or Sails. At first sight, they lag behind Rails in capabilities and they didn't stray far from web frameworks like Sinatra. We tried different ORM's, libraries for modular and integration testing, configurations of an application and much more.

It has become evident that there is no widely-adopted web framework that the community focuses on for joint development. While Express.js is a satisfactory framework, it is a micro framework that only provides routing and middleware capabilities. There is no single main ORM, and at least three popular and many unfinished or neglected projects exist. Additionally, there are four or five well-known libraries for modular testing and a similar number for integration testing, but they are not interconnected. To make an informed choice of a library or tool, each must be evaluated in separate demo projects.

Node requires writing asynchronous code, which can complicate and reduce code readability. In a small project migrated from Ruby/Sinatra to Node, the number of test lines increased significantly.

When writing in Node, one is writing in JavaScript, with alternatives such as CoffeScript/ClojureScript/other exotic options existing, though in 99% of cases, it is JavaScript. It is desirable to use the latest ES6 and ES7 standard features, but Node fails to promptly incorporate all of the constantly-added V8 features. To use these features immediately, transpilers such as babel must be employed to transform ES6/ES7 code into a language supported by Node. This results in difficulties, such as how to run tests, launch an application locally and in production, and set up tools for code analysis, test coverage, and performance.

What are the pros and cons of Node.js

After a month of using Node, we can identify the following advantages and disadvantages:

Advantages

  • Node gives you all the benefits of asynchronous non-blocking code. The web server manages the resources sparingly and can support more simultaneous client connections for a certain type of apps, where input and output (I/O) operations are performed actively. The implementation is at least not worse than alternatives on other platforms (Ruby/Java/Python);
  • You use JavaScript which is more or less familiar to any web developer;
  • Some libraries copy analogs from Ruby/Rails stack, so they are initially more comfortable to work with;
  • There are plenty of libraries/tools and they are rapidly developing.

Disadvantages

  • Absence of mainstream libraries/tools – each of them has many alternatives, the benefits and drawbacks of them are not clear from the documentation, you have to individually try each one and choose. There are many neglected projects. There aren't ready and complete solutions to many standard tasks, only hacks;
  • Very low integration between tools. If required, you have to write wrappers yourself;
  • The tools have not yet reached that maturity which we see in Ruby/Rails stack. They are developing rapidly but are still not functional enough for the level of comfort a Rubyist is accustomed to;
  • Once again JavaScript. This is not the best language and the latest changes in standards don't really save it. In order to get the latest standardized capabilities, it's necessary to add a transpiler such as babel.

What is the result?

For a common web application, which actively interacts with the database, Node.js' approach promises a significant increase in productivity. It works in our case as well because we make many HTTP requests to internal and external services.

Our transition to Node goes fast and smooth, the barrier to entry into the environment turned out to be not very high. The main difficulties so far are related to choosing libraries, studying them and comparing to each other.

On the other hand, after synchronous code, everything seems somewhat more complicated. Soon we will see how crucial it is.

The maturity of the ecosystem and the readiness of libraries for server development are still disappointing. We are going to put many efforts into integration of different tools between each other as well as into their revision and improvement.

Our acquaintance with this platform continues. In the meantime, if you are pondering the question, "Should I use Node.js development for my project?" and particularly if you are making the choice Node.js vs Ruby on Rails, our experience may give you some useful hints.