Rails or Sinatra: The Best of Both Worlds?
The Ruby world has been blessed with more than its fair share of frameworks for developing web applications over the years. Recently, though, two of them have emerged as the clear leaders in the field. Most readers of this site will have heard of Ruby on Rails. It was created by in 2004 by David Heinemeier Hansson and provides a MVC framework that helps to boost productivity whilst keeping developers happy. Sinatra was created by Blake Mizerany in 2007 and is a domain-specific language that wraps a lightweight HTTP request and response layer on top of Rack. It’s minimalistic approach is both elegant and classy. The stats at RubyGems.org certainly show how popular both of these frameworks are: Rails has 7 million downloads and Sinatra has 1.5 million.
Rails was the reason I got into Ruby web development, but in recent years I’ve been using Sinatra much more (and here are 7 reasons why I love it). In fact I have found that Sinatra, along with a few gems, is usually all I need when building an app. This led me to wonder whether Sinatra is suitable for tackling any project. When is is best to use Sinatra and when is Rails the right choice? To answer my question, I asked for the thoughts of some prominent Ruby developers.
Konstantin Haase is the current maintainer of Sinatra and feels that they both cater for different types of application:
They are both solving a different set of issues, even though they indeed overlap. While Rails is a framework focused on writing model driven web applications, Sinatra is a library for dealing with HTTP from the server side. If you think in terms of HTTP requests/responses, Sinatra is the ideal tool. If you need full integration and as much boilerplate as possible, Rails is the way to go.
David Heinemeier Hansson also believes that there was room for both of them, but feels that is is size of your app that should influence which one to use:
Sinatra is great for the micro-style, Rails is not. As long as you stay micro, Sinatra will beat Rails. If you go beyond micro, Rails will beat Sinatra.
In fact, most people tend to agree that Rails is better suited to big projects whereas Sinatra is a better fit for small micro apps or apis. David goes on to point out a general rule of thumb for choosing whether to use Rails or Sinatra:
If your app has 5-10 end points, there’s a real benefit to just rolling your own with Sinatra. Essentially if your entire controller structure can fit in a page or two of code, running it in a single file is great.
Sinatra works really well for the API, and smaller sites (internal apps, GitHub Jobs, etc).
David Heinemeier Hansson explains why Rails is such a good choice when it comes to building big web applications:
A large part of Rails’ success is by giving people a curated selection of the best technologies (“best” defined by me and the Rails community) ….
I change Rails every week to better fit what I’d want the perfect framework to be.
Konstantin Haase shares his enthusiasm for Rails and its philosophy:
I love Rails. Rails has been pushing the way we think about web applications. Rails is solving issues for you Sinatra never can, since it can make more assumptions about your application. You get everything set up for you, if you might need it or not, the biggest flaw in Rails’ architecture is to assume everything should be solved by a single tool.
There does seem to be a trade off when getting some features that you don’t really need in Rails, offset by the fact that you get lots of features that you DO need. This can be ultimately worth it, especially when it comes to creating a big project. Not everyone agrees that Rails is the only choice for a big project, however. Geoffrey Grosenbach of Peepcode Screencasts feels that this was ‘an outdated view that was only barely true of Sinatra in 2008 but certainly is not now.’ He highlighted the excellent Gaug.es app, which was built with Sinatra as an example that proves that it is more than capable of building a large-scale production site.
Despite this, Konstantin Haase highlights a potential problem with using Sinatra to create big applications:
Writing a more complex Sinatra application (or rather, an application using, amongst other things, Sinatra) requires the developer to spend way more time thinking about architecture and tooling. This is both an advantage a disadvantage.
Some developers would certainly see this as an advantage as they prefer the tight control over what goes into their application and understanding of how it all fits together. Geoffrey Grosenbach thinks that this is a trade off that is definitely worth it:
A huge benefit of Sinatra is its stability. You trade the convenience of a few Rails generators for your own design decisions. Writing in Sinatra can give developers and businesses API stability because the framework rarely changes. You own your code and you decide when it should change.
He goes on to say that Sinatra is the perfect candidate when it comes to building an application:
I start all my new applications in Sinatra and usually find that I don’t need any more than Sinatra together with a few Rack plugins, a simple CouchDB library, and Backbone.js for the front-end.
Sinatra fulfills all I need for a base platform and anything else I need I can either use gems or is already provided by cloud platforms and services (like Heroku and its eco-system of add-ons). Anything else left over I can write it myself.
In fact, this idea could be taken a step further by using Sinatra to roll your own bespoke framework that fits your needs perfectly. Start with Sinatra and then add in the gems that provide the features you need in order to create your own bespoke framework. In some ways, this is what the Padrino project has done.
David Heinemeier Hansson doesn’t see the point in doing this:
Breaking everything into tiny little pieces and having developers assemble everything on their own is the antithesis of what Rails is all about and how it won the framework game. Tens of thousands of man hours have gone into getting us to this point. Trying to reproduce that is a fool’s errand.
But while having more control over what goes into your app might be a nice idea, Konstantin Haase warns that this could take up a lot of your time:
The biggest disadvantage with Sinatra not solving the issue for you is, well, Sinatra not solving the issue for you. You actually have to deal with that issue. You might end up wasting too much time dealing with it.
And this is time that the developers simply may not have at their disposal if they are working to a tight budget. David Heinemeier Hansson is concerned that using Sinatra involves wasting so much time trying to reinvent the wheel:
the gains Sinatra offers you in simplicity are likely to quickly be offset with all the work you have to do replicate solutions Rails already provide. I pity the person who would try to build all of Basecamp, GitHub, Shopify, or any other major app in Sinatra alone. Rails is involved and large because it contains solutions to most of the problems that most people building apps of such scale will encounter. Trying to recreate all these solutions by hand is the anti-simplicity.
Ryan Bates, presenter of Railcasts feels that an advantage of using Rails is the amount of time that is saved when starting a project from scratch:
The default Rails app provides a lot that I need which requires extra setup in Sinatra. This can lead to faster development in Rails.
This sentiment is echoed by Rick Olson who believes that Rails made it easy to get GitHub off the ground:
I think Rails was a major asset to the founders [of GitHub] in the first year. They were able to take advantage of some of the higher level Rails features and iterate quickly.
The Rails mantra of ‘convention over configuration’ is cited by Chad Fowler(co-organizer of RubyConf) as another reason why Rails speeds up the development of big projects:
The Rails generators and structure provide conventions that Sinatra doesn’t.
The problem is that these conventions can sometimes feel like a straight jacket at times as Rick Olson points out:
Rails is fine if you agree with the Rails opinionated conventions, and stay on the “golden path.”
“Sinatra follows an abstract pattern: WDNNSP (We Don’t Need No Stinkin’ Pattern). WDNNSP means that Sinatra is beyond flexible, and it contains no preconceptions of how you organize your domain or business logic. It has no implicit folder structure, no default Database Abstractor, and no restrictions about how or where you use it.”
A lot of the appeal with Sinatra is being able to choose how your app is structured in every way. Using Sinatra can be liberating, as you are not restrained by size, structure or work flow. You can build an API, web application or pack your code up as a gem.
It may surprise some people to hear that David Heinemeier Hansson is also a fan of Sinatra’s simplicity:
I’ve used Sinatra in the past and I like it a lot. It offers an entirely different approach that’s great for a much smaller scope of problems, but does it really well.
So is there anything that Sinatra brings to the table that he would consider adding to Rails?
There’s nothing inherently in Sinatra that makes me want to redo Rails in other ways.
He admits, however that Rails nearly copied one of Sinatra’s coolest features:
We considered adding a single-file mode to Rails but rejected it because why would we want to optimize for something Sinatra already does so well?
Rails certainly provides a huge amount of features, but this often includes many that you aren’t needed – or they don’t work exactly as required. Rails 3 tries to mitigate this as much as possible by decoupling some of the different features, which can lead to a lighter and more confgurable exerience, as Chad Fowler points out:
Rails itself isn’t all that “heavy”, especially with the ability these days to trim it as you see fit.
Rails 3 introduced a lot of configuration options that allow you to tailor the experience to suit what you want to do. Despite the ability to cut out the cruft, Konstantin Haase warns that it is often just too tempting to keep it all in there, which leads to bloat:
In my experience, Rails apps often and up as one monolithic application. [not using Rails] leads to modularity, flexibility, fast test suits and scalability. However, you could reach the same architecture while carefully constructing Rails applications, it is just very tempting not to.
David Heinemeier Hansson doesn’t see this as a problem and feels that Rails is a good fit, whether you use all the features or not:
There is nothing practical gained by physically removing a piece of code in Rails that you do not use. Nobody is forcing you to use all features. [Many features in Rails] are entirely optional and can be completely turned off, if they rub you the wrong way.
Rails is becoming lighter and Sinatra has shown it can do the heavy lifting which means that there is an increasing amount of overlap between the two. Chad Fowler believes that, in actual fact, both Sinatra and Rails could be used for a variety of projects:
I think in truth each could be used for both ends of the spectrum. I suppose it’s a subjective choice ultimately.
The general consensus seemed to be ‘choose the right tool for the job, but the overlap between the two means that the decision of which to use often comes down to personal choice. Sinatra might allow you to have more control over the architecture, but is the extra effort a good use of your (or more importantly your client’s) time? Ryan Bates summarizes what type of person would be more likely to choose which framework:
In the end I think it depends on your preference, whether you like to start lighter and add as needed, or start heavier and remove something to make lighter if needed.
Geoffrey Grosenbach proposes that there are fundamentally two different types of developer:
I think there’s a massive divide between Ruby developers who prefer small, light, fast, explicit, and extensible vs. those who prefer full featured frameworks. Sinatra provides the former, Rails provides the latter. So I don’t think Sinatra will displace Rails. It’s just a different philosophy and appeals to a certain kind of developer.
But perhaps you don’t have to choose one over the other. Fellow Ruby Source author Dave Kennedy points out that Rails and Sinatra actually work really well together:
If anything recent developments have made the 2 frameworks complimentary. That said I’m working on a multi-tenant application at the moment that uses Sinatra heavily within a Rails app, some pretty cool stuff. Sinatra has let me modularise my app in a way I have not been able to do before so easily.
A number of people point out that the ability to mount Sinatra apps in Rails 3+ means that you really can have the best of both worlds. In fact Chad Fowler feels that the whole concept of choosing one over the other is meaningless:
The ability to mount Sinatra apps inside Rails 3 apps makes it a choice you don’t need to worry too much about.
Geoffrey Grosenbach feels that this will give apps a more modular feel:
Many people are embedding Sinatra apps inside Rails apps. This mimics the design of the Django framework, where an app consists of many smaller apps that handle specific parts of the app (and are often reusable between apps).
David Heinemeier Hansson also feels this was a nice way of doing things:
You can even have micro Sinatra apps inside your Rails structure. GitHub has that for a few things. Nice model.
Rick Olson ellaborates on how GitHub frequently use the pair in tandem:
I’m very thankful that Rack and Sinatra integrate so tightly with [Rails]. Rather than trying to force Rails to your will for a specific feature, you can route the request to a Sinatra or Rack endpoint and do exactly what you need.
Everybody agrees that there is a place for both of these frameworks in the Ruby web ecosystem. In fact, they work incredibly well together and in many ways complement each other to a certain degree. A lot of people seem to think that the two frameworks work best together and fill different needs in general. Where there is some overlap, they appeal to different types of developers. They both do what they do so well and are exceptional examples of good practice – so much so that they have been copied to death in other languages. This is brilliantly and succinctly summarised John Nunemaker of GitHub:
They both have their place. Rails is better if you just want to get things done. Sinatra is better for simple things and for when you want to control everything and use your own opinions.
As a community we are so lucky that we have such well developed tools that are so well supported and open source. Both Sinatra and Rails cover all the bases so well, that they really do give us the best of both worlds.
What do you think – have you used Rails and Sinatra, do you prefer on over the other? Would you consider Rolling your own framework instead of using Rails? Leave a comment below.