Choosing Backends: Ruby/Rails vs JS/Node vs Python

Choosing Backends: Ruby/Rails vs JS/Node vs Python
The logos for Ruby, Python and Node Js

Over the past decade, I've worked on many projects with various different backends - but I've had at least 2 years of professional experience with each of the following: Rails, Node and Python (mostly Flask, but some Django) as back end solutions. So, I wanted to write a quick overview of what my takeaway was of the differences of the three in practice, with scenarios about when you might want to use each – and what some misconceptions that I ran into along the way.

It's worth stating up front, most of this experience has been as a consultant or an early dev at a startup, so all of these projects were very new and the primary purpose of development was to find product market fit, not to scale existing products. So, this advice is going to be through that lens of what might be good for a new project. I haven't worked on large projects at significant scale (say, over 100k users) but my impression is that, it's often difficult to escape the need to rewrite significant sections of the code when you get to that point. Part of the reason for this, is you need to get more specialists in to optimize the specific areas that are failing to scale. But, the good news is, if you have over 100k users, you probably have a lot more resources than you did when you had zero users.

But, for a new project that is seeking to get off the ground, what are the advantages of each?

Ruby on Rails

So, I have to admit a little bit of bias here; Rails was my first love that I never really got over. For my first job, I spent a year debugging C++ code on a 20 year old codebase (I actually don't remember delivering a single feature that year, I just remember fixing bugs.) Then I learned Rails and switched to being a web developer, and the experience was like night and day.

I went from – basically – grinding away for a year with minimal visible product impact to being able to deliver entire applications in weeks (or, even days sometimes.) It was intoxicating. For my money, I don't think any framework can match Rails for development speed (it's hard for me to know for sure because it's the framework I've used the most, but I get the impression talking to other devs that they feel similarly.)

The famous "Rails demo" that put it on the map was How to Build a Blog in 15 Minutes – and back in 2005, that was truly revolutionary. Both Ruby and Rails were created primarily with the aim of developer ease, and what that functionally means, is that the devs have to put less effort into supporting the infrastructure of the website itself, so they can devote more time to features. One particular example of this, is Rails is considered an opinionated framework. What that means is, most Rails project tend to be structured similarly, and Rails kind of guides you down a particular path of development.

Now, if their default structure works for your purposes, that actually saves you a lot of time, because those are conversations and decisions about project structure that you don't need to have. I was actually surprised (and frustrated) to find that other frameworks weren't like this. Instead of just knowing where to put everything, you have to decide on a layout for every project and I definitely find that slows you down at the beginning. Additionally, especially as you pull other devs into the mix, I find you more frequently need to change the project structure than you do on Rails projects.

Additionally, Rails provides really solid helper functions and (personally) I think ActiveRecord (the standard Rails ORM, aka, mapping layer between the code and the database) is the best out there – or, the best that I've used anyway. I often find myself needing to re-write functionality that would have been free in Rails in other frameworks. It's also worth noting, Rails scales pretty well for sort of standard to mid-level usage; yes, if you get Twitter-big you'll probably need to re-write it, but it can carry you a long way before then.

The downside, of course, is if you're doing something weird or unusual you now have to hammer a square peg into a round hole. Where I would say Rails breaks down, is that the same mechanism that speeds up your development also gives you less control over the lower level parts of the application. Rails becomes less valuable on less standard projects (e.g. NoSql databases, pure APIs, etc.) and if you decide to do a large departure from the norm (for example, if you decide on something like a non-RESTful back end) you could end up fighting Rails more than it ends up helping you.

Python Flask & Django

So, while the framework I enjoy coding in the most is Ruby on Rails, the language I've seen the coolest stuff happen in is Python. Where Python really shines is that many academic libraries are written in Python – this includes libraries for image processing, machine learning, data science, etc. Effectively, Python is the language usually preferred by universities, so it has a lot of support around these types of high performance libraries that are doing a lot of cutting edge stuff.

Now, you don't necessarily have to have your web framework be written in the same language as other scripts/resources on your project, but there are some advantages to it on a small project – especially around hiring. If you get a small team who are very strong in Python, they'll be more able to work all over the project instead of being siloed. And, you do also leave open the possibility of incorporating your scripts into the web app if appropriate, which wouldn't be possible if they were written in different languages.

Most of my experience with Python has been Flask, which is a much lighter framework than Rails or Django – and we picked it because the projects were more custom, and not expected to scale significantly. (For example, at my last startup where we used Flask, we needed to connect to custom hardware that was deployed out in the field, but we didn't expect to get more than 100 customers in the first two years.) My brief experience with Django, is it is similar in concept to Rails but slower to develop in. However, I expect it would scale better than Flask (though, apparently, it's not quite as scalable as Rails) and would be a good choice for a larger application that would benefit from access to Python's many libraries.

I would likely choose a Python based framework if I were working on something AI heavy (e.g. neural networks), data science heavy, or image processing heavy. I'm sure there are more areas where Python would be the best language (relative to the ones discussed here) but those are the 3 areas I'm most personally familiar with.

Node

So, technically Node isn't a framework; it is an engine that lets you write javascript on the back end. However, I have always used Node with Express, and Express is a web framework similar in concept to Rails, Flask, and Django.

In terms of temperament, though, Express is basically the opposite of Rails, in that it is an unopinionated framework. This caused me a significant amount of stress when I was first working in Node/Express, as I would regularly google "best way to structure express app" and things like that. So, because of that, it's a solid match in effectively the opposite use case of Rails; if you're working on something highly customized, and you either don't expect to scale significantly or you have the resources to devote to scaling your Node/Express app.

So, back in like, 2016 or so everyone thought MEAN was going to be the next big thing - MEAN means a Mongo Express Angular Node stack. In particular, the inclusion of Mongo, which is a NoSQL database, was very interesting and potentially revolutionary. Mongoose is a library which was the standard Node ODM for Mongo (an ODM is like an ORM, but for non-relational databases) and I heard top Node developers say that, if Mongoose could just get a little bit faster, then Node and Mongo would start to take over the world, and NoSql database would start replacing relational databases everywhere.

It was a nice idea but... it never happened. And, it never happened because there are some fundamental limits to non-relational databases that are very hard to get around. Without getting too out of scope for this topic... non-relational databases are really good for writing data fast, but they're usually slower at getting data – especially, "relational" style data, which most web applications tend to need. It's a shame, because there are many development advantages to NoSql – but it was not meant to be.

What this functionally means, however, is that the NoSQL support for Node/Express was primary, and SQL support came later/was a bit less developed. Because of this, I find the SQL ORMs to be better supported in both Rails and Python stacks than in Node/Express. Conversely, Node probably has some of the best NoSQL libraries out there, and is a likely a good choice if you're using an app that is amenable to a NoSQL database (heavy writes with few reads is a good example of this.)

Then finally, I'll give one reason people often say they want to use Node that I disagree with – that "it's easier for the front end developers to make changes on the back end because they already know javascript." Here's the problem with that; javascript is actually a much more difficult language than people appreciate. It's easy to get up and running with it, but it's damn hard to master. Not only is it hard to master, it is actually very easy to make subtle mistakes. Javascript is a bit unusual for a mainstream language, because it is a prototype based object oriented language.  However, many libraries written in javascript will often abstract the prototype layer away, to try to make it look like more "normal" object oriented languages. Functionally what this means, is that different libraries in javascript can be so different they almost feel like they're written in different languages. Writing a React app feels very different from writing a Node app, so I don't think there's much to be gained with language consistency when it comes to javascript.

A solid front end dev will usually be able to pick up enough Python or Ruby to do minimal back end changes anyway. I believe, a better approach to giving your front end devs more flexibility on the back end, is to make sure you have some areas of the back end code that you keep minimal and clean, so they can use those as "examples" to copy off of when they're creating modifications.

Summary/TLDR

So, if I had to break it down, I'd say use Rails for standard applications and fast development, use a Python framework if you're going to need access to cutting edge academic-style libraries, and use Node if you're doing something weird, or if you want to use a non-relational database.