The year was 2013, and I was asked to build a project called 1500. The project was about providing email forwarding service using numeric email addresses:
[email protected]. At that time, I was a Java developer at work and I mostly used PHP for my side/freelance projects.
PHP felt fun and fast. I liked it way more than Java, mostly because the “save to reload” feature. Although I had a tremendous love for PHP, I secretly wanted to give a try to Ruby on Rails. For starter, learning a new programming language is always a good decision. Second, the tech media was all about Ruby on Rails these days. Given these reasons, choosing Ruby to tackle the 1500 project was obvious to me.
Coming from a simple project in Laravel 3, I found Rails to be much more mature, yet I could see the common things around them. I even told one of my colleagues how much they resemble each other. There were lots of tutorials that helped me finding my ways around Rails. Starting a new Rails app was in the flick of
rails new my_app. A new directory was created, with
config directories in it. Even
.gitignore, which was pretty new to me. See, during that time I used SVN at work and since we work in an isolated network, I have used git just several times beforehand! Fast enough, I started generating models and controllers via
rails generate scaffold command. It was simply awesome and helped me a lot for making the website.
I have never used a package manager before, so Bundler blew my mind. Never thought I could just find a package on the internet and give it a try by running a command. I still wrote lots of the code I could get from RubyGems myself, but the change was vivid. To this day, I think that one of the greatest things around the Ruby community is that they can choose a great product all together. When I searched for
Authentication, all the blog posts were the same. I felt like I shouldn’t worry myself and just trust the system and use gems.
- Every ruby blogpost, like, ever.
The only bad thing I had to say about Ruby on Rails was its slowness. GOD IT WAS SLOW. I had fun writing this project, but developing in Rails felt really slow to me.
Over the last years, I started to discover my interest in Node.js. When I first tried Node.js, it was by running a simple
express server. I loved using
sinatra for small demos and it felt WAY faster than Rails. So when I saw that the
express docs stated that its basically “Sinatra for Node.js”, I had to try it. I ran it and forgot about Ruby instantly. It felt BLAZING FAST.
node index.js and BOOM listening. No games, no jokes.
Leaving frameworks like Ruby on Rails made me leave MySQL and other tabular databases since I was not a fan of the SQL syntax, especially the DDL, and I had no migrations. I tried to use MongoDB and really done it for some time, but I never was fan of it. Then, I found
RethinkDB, which is still pretty awesome to me. I even wrote my final project for my CS degree using RethinkDB.
For most of my daily usage, RethinkDB was slow. I needed joins, aggregations. I thought that PostgreSQL might work better. Not so long afterwards, I fell in love with SQL databases again. The declarative way of writing SQL was great, and looked way better than my imperative JS queries and joins in MongoDB, and was way faster than the RethinkDB REQL queries.
db-migrate to use migrations for my local and remote database and even wrote myself a new, simple, composable, querying system I wrote about in another post.
The last six months were hard for me. I finally realised Node.js has its disadvantages too. In every project I started I had to install
babel-preset-stage-1. In every project I had to think about the directory structure. In every project I looked up for might-be-better alternatives for the modules I was using the project before.
I have realised that most of the modules are very specific, and for a very specific mindset. That means that multiple coding styles are introduced in your codebase. Heck, I have even wrote my own db querying system. And this is a problem. See, I can get out of focus pretty easily. When I find an interesting problem, I usually think about how to solve it — even if the project could continue without solving it.
And that what Node.js made me do. Think about stuff I should not think. Why does every project have a different structure? When I go out and take a new developer for my team, would he know how the project is built? How much time would I spend on explaining the decisions I’ve made?
Well, if I need lots of time to explain my decisions, they aren’t that good.
So three years after my last usage of Ruby on Rails, I have decided to give it a chance again.
gem install rails && rails new my project. And I was fascinated.
Looking back to the past isn’t always fun and nostalgic. I tend to think “ohhh how stupidly cute I was” on most of my Facebook posts as well. There are posts I read and flush immediately. Coding is no different.
I am a different software developer now. Three years ago, I didn’t care that Rails generates test files for every model, controller, etc. I actually removed all the tests. Yes, this is me three years ago. People change and the code they write and the quality of the software they ship change too.
Since the time I left Rails, it got way better. No, I haven’t used ActionCable yet, I’m talking about the the things you use daily. Having
spring on every new Rails project is awesome. It makes it way faster to run the console and your tests. I recently learned a lot about RSpec, and it is such a fantastic tool. I haven’t really tried writing tests in Ruby beforehand. The hot code reloading works like a charm and feels way better and faster than using
nodemon. Basically, spring and hot reloading combined give one hell of a fight to the Node.js development environment.
The startup for Node.js was and still is very fast.
$ time node -e "console.log('hey')" hey 0.06 real 0.05 user 0.01 sys
With only 0.06s to run this command, there is no wonder Node.js was so attractive to me. If we run the ruby command that does the same thing:
$ time ruby -e "puts 'hey'" hey 0.12 real 0.02 user 0.04 sys
Oh, that’s double the time. Not that slow either, but still, double the time. Yet, I think that the commands above are lying to us. We almost never “just running node” or “just running ruby”. Running plain ruby scripts is cool, what was slow was Rails! And in Node land, I never use Node.js by itself in a real project. I find myself adding Babel, and sometimes even Flow, to any project I develop. I actually have 2625 modules called
babel in my development directory. So let’s print “hey” using
$ time babel-node -e "console.log('hey')" hey 1.04 real 0.93 user 0.14 sys
Oh man! this is much slower than Node, obviously, but also — It is way slower than Ruby! Still we need to check on Rails.
$ time rails runner 'puts "hey"' Running via Spring preloader in process 50596 hey 2.18 real 0.25 user 0.04 sys $ time time rails runner 'puts "hey"' Running via Spring preloader in process 50609 hey 0.47 real 0.27 user 0.04 sys
So, the first time we launched Rails, it was slower by more than 2 times slower (one second) than
babel-node. Yet, thanks to
spring, The second time we’re launching our script, it is 50% faster than
babel-node! This is a huge difference since it reflects the tests you run, the REPL, everything.
It’s clearly not over.