You and Node.js, or <insert other framework here>, don’t share a lot of the same values.
It’s okay. There are a lot of fish in the sea. You’ll be just fine.
Typical Pedantic Developer Disclaimer
Bear with me, I’m going to start this off by deflecting some early criticisms. I want to say that Node.js, and many of the frameworks built on top of it are great tools. There is a whole world of problems that Node.js is perfectly suited to solving. In fact, I would say that many of the best places for Node.js to plug in are at companies that have strong engineering cultures like Netflix, LinkedIn, Paypal, etc… Places where there are large teams of skilled engineers who want control over every line of their application, need insane performance, and who want to make the tradeoff between using the latest tools… and having to keep up with those tools as they change (or just write their own tools).
And yes, I know that Node.js is a runtime and not a framework. I really do understand that. The problem is that the Node.js ecosystem has a huge number of popular frameworks, so picking one and using it as an example would just get me yelled at by everyone else. By not picking one, I just get yelled at by everyone.
It’s Not You, It’s Me
Okay Justin, so you agree that Node.js is great technology, then what are you trying to say? Node.js is exploding in popularity right now. Why wouldn’t I want to use it for my business (or startup)?
Well first, I’m not saying you don’t. There is a good reason that Node.js is popular. It comes with a lot of legitimate strengths:
- Scalable – Node.js uses event driven I/O which means that it can handle a ton of concurrent connections. So it might not be fast as something like Java in pure speed, it does allow a ton of lightweight connections on the same process.
- Simple – In general, the Node.js ecosystem values small frameworks that do one thing well, which can allow developers to get in and get started quickly.
All I am saying is that before you choose to use Node.js on your next project, consider a bit what your needs and goals are.
For example, what is more important to you, flexibility or productivity? Do you value an integrated toolset that pushes (forces?) you down a particular path, or do you want the flexibility to mix and match all of your tools? Now you might be saying “Of course we value flexibility AND productivity!” And that is great, of course you value both, but what do you value more? There is no wrong answer here. There are a lot of companies that value control and flexibility over productivity, and for very valid reasons. Both are practical, but both are very different applications of practicality.
What is more important to you, flexibility or productivity? Of course you value both, but what do you value more?
The Spectrum Of Control And Productivity
There are companies that need total control, and there are other companies that want to spend less time focusing on their technology, and more time focusing on their business problems. I like to think of these companies as falling on two opposite ends of a spectrum. On one side you have companies that just want things built quickly and for them to be somewhat usable, and somewhat functional. On the other extreme you want companies that want to write everything themselves, and even go so far as to do things like write their own web server software (I’m looking at you Google).
For right now, I just want to focus on the “Full Stack” – “Lightweight” portion of the spectrum. To understand the difference between these portions of the spectrum, I’ll use the example of user authentication and registration. Below is a post detailing how to add authentication and user registration to a node.js app using passport:
That’s a thorough and great tutorial! The steps that tutorial goes through are:
- Pulling in passport
- Setting up your app to integrate the passport middleware
- Adding a database.js config file
- Creating the routes file and wiring it up to our views (we would probably want to move these routes out into another file in a larger app)
- Put the code in to login/logout the user
- Create views for signup/signin/signout
- Create the user model
- Add code to the user model for hashing the password,
- Checking if the password is valid
- Configure the passport local strategy to load the user and authenticate it
- Set it up to return any validation errors, etc… from login
There is quite a lot of code and configuration there. Many developers love the explicitness of wiring everything up like this, they hate it when frameworks hide things behind magic. It’s cool, I get it! There is a certain simplicity to it. However, if you’re like me, and you love “batteries included” frameworks like Django, Laravel, or Rails then you probably look at this and think that you’d rather just leverage the community’s work and knowledge and let the framework handle it. I can get the functionality really easily, and I know that my framework’s built-in authentication system gets a lot of use and is probably pretty high quality.
Time For Some Apples and Oranges
As a comparison, both Django and Laravel ship with authentication out of the box. The Rails community largely uses Devise as its authentication method. Just to give an example, here is how you’d setup Devise in a Rails app:
- Put Devise in your Gemfile, run bundle
- Run ‘rails g devise:install’
- Run ‘rails g devise user’
- Run ‘rails db:migrate’
- Optionally run ‘rails g devise:views’ to spit out the default views for customization
I’m not saying that one is inherently better than the other, they are just different. But one thing to note is that Devise gives you a *lot* more functionality out of the box than what the above tutorial provides. You’re really only just scratching the surface there. The important thing to note is that a Node package couldn’t ever provide this functionality. Because one of the things the Node.js ecosystem values is ultimate flexibility, you cannot depend on there being defaults. Because Devise knows where views go, how to wire in routes, where controllers go, where to generate a model, how to wire up validation, how to add helper methods to controllers, etc… it can do all of this work for you.
The same holds true for a whole world of Rails gems (and Django or Laravel packages) that do everything from authorization to logging. Need a library to automatically take all of your CSS for your emails and inline it into the HTML at runtime so that it renders properly in most email clients? Yep, there is a gem for that. Need a library to automatically save versions of a specific model every time you save it to the database? Yep, there is a gem for that too. Do you want a simple, no configuration way of pulling webpack into your Rails app? Yep, you guessed it, it is now part of Rails. And yes, the goal was for it to work out of the box without any configuration, and to automatically combine, minify, and hash your assets. It even provides easy integrations for popular front-end libraries and gives you an easy way to spin up a webpack dev server.
It Isn’t Better, Just Better For Me
You see, the values in the Rails ecosystem are just different. DHH tried to elucidate those values a few years ago by publishing The Rails Doctrine. In it he explained the nine pillars that make Rails what it is, and why it continues to flourish. I know that Hacker News these days might make it seem like Rails is on life support, but the reality is that Rails had almost 4700 commits over the last year. That number is absolutely insane, and flies in the face of comments that Rails is dead or dying. I know that commits aren’t the be-all-end-all of activity measurements, but there are very few tools or frameworks that are anywhere near as active as Rails.
Now I know what you’re probably thinking. Justin, if you love Rails so much, then why don’t you just marry it? And to be honest, I really do like Rails. You might say I love Rails. For much of the work I do, I don’t think any other framework has done such a great job of providing me the basic building blocks for quickly and easily building a production web application. But my idea of what a makes a production web application probably varies a lot from your definition, and that is the whole point.
But my idea of what a makes a production web application probably varies a lot from your definition, and that is the whole point.
I think that too far too often the default tech stack for new projects is chosen without ever stopping and considering the real needs of the business. Many companies want to have applications that are built on frameworks that are moving and changing quickly, while other companies value more stability. Some companies want to choose every piece of their stack, while other companies want a set of constraints that allows them to focus more time on solving business problems.
Just Consider It
I just ask you to think about it. The next time you’re starting a project, take a bit of extra time to really think about the needs of the business and then carefully consider your choice of stack. Does your business really need ultimate flexibility? Even if it comes at the cost of lower productivity?
Maybe what you’re doing now works great for you! Awesome! But remember, don’t just go with the flow, you don’t have to use the same thing all of the cool kids are using (although that sure sounds like a lot of fun!). Sometimes it is better to use mature and stable technologies.
If, after a month of monastic-level solitude and quiet contemplation of all of your life choices, you decide that you could use something a little more full-stack; then I recommend checking out the following frameworks:
Rails – Ruby – I just spent a couple pages blabbing about this, I doubt I need to tell you much more.
Django – Python – Django is actually slightly older than Rails, but is also a wonderfully powerful stack. It has gained a lot of popularity with the rise of Python over the last few years.
Laravel – PHP – I haven’t used Laravel in anger, but I’ve talked to several people who love it. If you’re in the PHP world, I’d recommend checking it out.
Phoenix – Elixir – A framework built by a prominent member of the Rails community. Built on BEAM, the Erlang VM, it is designed to be productive and fast.
Do you have anything you’d like to see added to that list? Let me know!