The Road to Sinatra 2.0

Mon Apr 18 18:21:57 2016 Zachary Scott

Greetings and salutations!

Let's talk about the current state of our beloved Sinatra library, and our big (ok not so big) plans for the next major release.. TWO POINT OH!

Too Long; Did't Read!

I'll cut to the chase, for those who are short on time:

While, I could fit those in a mini-tweetstorm, I saved your timelines for this blog post.

Some background

In case you didn't know, I joined the Sinatra team in 2013 and since helped release about one stable release per year.

This is my personal limit, but the team has recently expanded with the help of these awesome people!

Along with their help, we will be giving our best effort to share the maintenance burden to ensure Sinatra remains stable.

Before we get into the details of what and why, I'd like to answer some questions that will probably come up.

Is Sinatra 2.0 a major rewrite?

No. The largest changes are dropping unmaintained Ruby and Rack version compatibility. Most if not all of the existing API and features should still work.

Will my app still work?

Maybe. It depends on if you're app is compatible with modern versions of Ruby and Rack.

We actually aren't deprecating any features, and there are no warnings, so if your app breaks somehow please file a ticket!

Your help testing unstable releases will ensure Sinatra remains production ready!


As I was saying, we've made 3 releases in the last 3 years.. all of them point-releases (1.4.5, 1.4.6, 1.4.7).

Sinatra is stable, as stable as it gets IMO. In fact, the last release of Sinatra still supports Ruby 1.8.7.. which was released 8 years ago!!

So what will happen?


We still plan to maintain Sinatra version 1.x in the foreseeable future, since it's actually relatively low-bandwidth to maintain.

All future 1.x releases will be cut from the stable branch.

The reason why we're branching is to make unstable development of the next major release easier for collaborators. Previously we had an experimental branch for development, but found things quickly became out of sync and there were too many duplicate patches being sent.

What about 1.5?

At the moment, there is no plan to release any 1.5.x version.

The reasoning here is that 2.0.0 shouldn't break any major API compatibility. We will, however, break some version compatibility so we'll use the major version bump to let users know about it. I'll get into this more in a moment.

There was some thought to use the 1.5 series to support both new versions of Rack and legacy versions of Rack, to act as some kind of shim for upgrading users.. but to me this seems like a time sink.

Rack version what?

Yes, I wasn't exactly clear here -- but since Rack is making a major version change we will only support the Rack 1.x series with Sinatra 1.x (a.k.a "stable").

At the heart, Sinatra is really a Rack extension, and IMHO this makes more sense to have the version parity be more obvious for users. That said, version parity is NOT my goal :)


So what about the development branch?

From here on out, we will use the master branch for developing Sinatra version 2.0.0.

This will allow us to, hopefully, move faster without the overhead of keeping a separate branch in sync. As well, anytime someone sends us a patch for HEAD it will be automatically applied to the latest edge version of Sinatra; removing any confusion for contributors which branch they should pull request to.

At this point, the maintainers can decide whether a commit or patch should be backported to the stable branch. This is not something contributors should have to worry about.

Ruby Version Compatibility

By targeting Rack 2.x, this also means we inherit the Ruby version support of Rack 2.x series. So only Ruby 2.2.2+ will be supported. Since Rack 2.0.0 is still only an alpha release at the time of writing this we will assume Ruby 2.2.2 -- but this may change by the time the final is released (no promises ;))

From here, we can work on using the latest features for modern Rubies and remove any legacy cruft laying around (hint: low-hanging fruit contributors).

All The Gems

Apart from the version changes in Sinatra 2.0.0, we'll also be making some changes to the organizational structure of Sinatra core libraries.

This includes rack-protection, sinatra-contrib and mustermann.

We'll be bundling these libraries with the main sinatra/sinatra repository to cut down on number of bug trackers we have to maintain.

Unfortunately, these projects tend to be neglected more than the main repository and quickly fall behind supporting the latest changes in Sinatra. Bundling will also help solve this as we can run all of the test suites for each project anytime one of them changes.

Think of it like how Rails bundles all of the action- and active- gems into one repository.

Now let's talk about what each of these gems are and how they will be affected.


This gem is designed to provide several middleware for protecting your applications against common web attacks.

We ultimately want to make this a dependency on Sinatra itself, so that every application can take advantage of it.

First though, we need to sort through some older issues and make a release prior to merging this gem into core.


This gem provides a bunch of helpful extensions for common patterns that can be applied to your Sinatra application. Take a look at the documentation for a list of what you get.

Historically this gem has been maintained along side Sinatra, but previously we had a seriously hard time getting it updated because the dependencies had bitrotted. The build was broken for so long, and we had no idea why since it doesn't get much contribution traffic the builds simply weren't running.

After making a stable release of the gem, I'm excited to merge some of the features that have been waiting on me to merge.

Although these extensions will be bundled into the repository, it will still be shipped as a separate gem to avoid bloating the core sinatra gem package. Another benefit to bundling this gem is hopefully encourage more contribution to the Sinatra project by making it a first-class citizen to the repo.


Lastly, we have "The Amazing Mustermann" which will be used to replace the pattern matching system for Sinatra's router.

Mustermann is a powerful library with many features and compatible params parsing interface. You can read more about it's features and usage in the README.

The main difference between Mustermann and the existing router is implementation, but essentially it builds an AST internally and builds pattern objects rather than using regexp objects. If you're familiar with Journey, the Rails router, there are some similarities (hand waves).

It seems radical to change one of the core components of Sinatra, we all know URLs are the key to HTTP and since Sinatra is actually just an HTTP library.. well. I know this is asking a lot, but we think you will come to appreciate the benefits of a full routing engine.

All of your existing routes should still work, and you should see no real change in performance. Mustermann is already being used in production by Travis CI for some time now without any issues, so I'm confident that there should be no real-world impact on the stability of your applications.

Wrap up

That should cover all of the upcoming changes and plans for Sinatra.

In order to close out this blog post, I'd like to leave with some actionable items for anyone who made it this far! Congratulations, if you're reading this I can only assume you care about the future of Sinatra and how it will affect you. This is very important because you, yes YOU, also have a chance to impact the future of the project. Here's what you can do:

There might be more, but I can't think of them right now.

If you want to pitch in or have any questions you can reach me on twitter at @_zzak or!