Sinatra and Bourbon – Web Development My Way

Share this article

When you think about Sinatra and Bourbon, web development might not be the first thing that comes to mind. (It’s certainly not the first thing Google suggests, and I’m not the first one to notice that.) But when I’m starting a web application project, Sinatra and Bourbon go together like, well, you get the idea.

Early Decisions

Picking a framework for back-end web development is one of the most critical early decisions, whether you approach it from the back end or the front end. For many Ruby developers, the obvious choice for years has been Rails, with its huge community and comprehensive “convention over configuration” convenience. But recently the framework that has been inspiring the most versatile imitators, such as Express for Node and Laravel for PHP, has been Sinatra.

Similarly, on the front end, there have been several popular frameworks such as Zurb Foundation or Twitter Bootstrap that offer to handle all your front-end concerns as long as you follow their conventions. But for people who want the most flexible and the lightest-weight solution, there are few solutions that are as unobtrusive while being as comprehensive as Thoughtbot’s suite: Bourbon, Neat, Bitters, and Refills.

The stack I like to start with when kicking off a new project these days is a combination of these two powerful and low-key packages. The only tricky part is getting them to play well together. But once you have that problem solved, there’s no end to where you can go with this combination.

The Sinatra Advantage

Sinatra is a leaner, more lightweight way to structure a web application than Rails. Among the advantages of Sinatra are its simplicity and its unopinionated approach to development. If you prefer to structure your entire application as a single page of Ruby code, you’re more than welcome to do that. And it’s that apparent simplicity that led some people to ignore Sinatra in favor of its more comprehensive cousin, Rails. But when you want to grow into more complex code organization, Sinatra will be right there with you.

Frameworks in general are designed to make it quick and painless to get a project out of your head and out into the world. But when you start to get into the meat of publishing and maintaining your web application, you may start to bump your nose against the limitations of the early choices you made. It’s not usually a good idea to try to predict too far in advance where your unique product is going to need to go as it finds its market.

With a highly opinionated framework such as Rails, you may find your work cut out for you if you decide you want to make changes that aren’t natively supported by the way Rails structures its code. Although Rails has gotten better about flexibility over the years, once you buy into a comprehensive framework that tries to do everything for you, any deviation you make to suit your particular needs risks complicating the convenience that drew you to the framework in the first place.

On the other hand, Sinatra’s simplicity encourages you to develop your application’s api the way you want to, incorporating the gems and other Ruby tools that suit your purposes. Because Sinatra doesn’t try to perform a lot of magic behind the scenes, an application you develop with Sinatra is more transparent and more versatile in the hands of a developer with her own opinions.

The Bourbon Advantage

Like Sinatra, Bourbon takes an approach that allows the front-end developer to choose the parts and pieces that make the most sense for a particular application, and leave the optional bits behind. Building on Hampton Catlin’s popular Sass extension language for writing precompiled CSS, Bourbon provides everything from convenient mixins, a grid system, and typographical formatting to baseline design choices and a growing library of standard widgets and components. And the cool thing is that all of it is optional.

Working on the front end, the issues of cross-browser compatibility, client-side processing power, and network-dependent latency are all critical to optimizing the user experience. While comprehensive frameworks try to take a lot of the decisions out of the hands of the developer, frequently that comes at the cost of forcing more than is needed into an otherwise simple site. That can lead to bloated downloads, congested servers, and slower painting or page refreshing when it’s most critical.

With the Bourbon approach, you can focus your optimizations on the areas where they matter most in your application. By picking and choosing each component consciously, you have the opportunity to decide for yourself whether you want every page on your site to carry the CSS and JavasScript that’s only needed for components that show up on a path fewer than ten percent of your visitors will ever see.

Getting Them to Play Nicely Together

Once you’ve decided to take a lean approach to your web application, there are just a couple of tricky bits to keep in mind when integrating Sinatra and Bourbon.

One of the ways that Sinatra adds value to your development process is by taking control of your asset pipeline and your routing. It’s a simple formula, but it’s not exactly what Bourbon is expecting out of the box. However, it’s not difficult to make Sinatra serve your Bourbon site.

I like to use a code structure like this for my Sinatra applications, which makes it easy to keep my Sass and Bourbon code up to date as I work, and also makes deployment to a hosting site such as Heroku very convenient:

views\
   sass\
       base\
           ...
       bourbon\
           ...
       neat\
           ...
       main.scss
       normalize.scss
   layout.haml
   index.haml
Gemfile
app.rb
config.ru

The first thing to do is to include the required Ruby gems in your Gemfile, and then run bundle install to download them and make them available to your application. Here’s my starter Gemfile:

Gemfile

source 'https://rubygems.org'

gem 'sinatra'
gem 'haml'
gem 'sass', ">=3.3.0"

# dev
gem 'shotgun'

You can see that I’ve specified Sass version greater than 3.3.0, to support the Bourbon libraries correctly. I also include gems for HAML, my favorite shorthand for writing HTML templates, as well as Sinatra. In the development environment section I also like to have Shotgun available, which supports instant reloading of my Sinatra application whenever I make a change to any of the files.

I include a config.ru file to make rack launching and deployment more convenient. Here are the basics that go into this file:

config.ru

require 'sass/plugin/rack'
require './app'

use Sass::Plugin::Rack

run Sinatra::Application

With this in place, my server will know how to integrate rack with Sass, and also where my application lives so it can be started. This should work with hosting services that support Rack and Passenger as well.

The next step is to create a basic Ruby app.rb file to set up Sinatra and tell it where to find my layouts and templates:

app.rb

require 'sinatra'
require 'haml'
require 'sass'

configure do
  set :scss, {:style => :compressed, :debug_info => false}
end

get '/css/:name.css' do |name|
  content_type :css
  scss "sass/#{name}".to_sym, :layout => false
end

get '/' do
  @product = "Short Description of Product"
  haml :index, :layout => :default_layout
end

The require commands pull in the gems, and the configure block just tells Sass how I like to write and output my CSS. There’s a little trick in the first get block, just to let Sinatra know how to convert the files in my Sass directory to symbols and interpret them as CSS. The final get block creates an instance variable to pass to my first template, and tells Sinatra to process the template with HAML, using the default layout.

So all I need now are the templates and layouts in my views/ directory:

views/index.haml

%h1= @product

views/default_layout.haml

!!!
%html
  %head
    %title Sinatra App
    %link{:rel => 'stylesheet', :type => 'text/css', :href => 'css/main.css'}
  %body
    %section
      = yield

And a basic main.scss file in my sass directory to import all the Bourbon files I might want to use, along with Normalize, a third-party reset recommended by Thoughtbot:

views/sass/main.scss

@import "normalize";
@import "bourbon/bourbon";
@import "base/base";
@import "neat/neat";

Running the shotgun command starts up your local server at http://localhost:9393, and navigating to that URL in your browser should show you a basic page with minimal CSS.

But all the power of Bourbon is there, right on top of your Sinatra application. To demonstrate the integration of Bourbon, I can incorporate one of the simpler Bourbon Refills, the Hero component, into my index.haml file:

views/index.haml

.hero
  .hero-inner
    %a.hero-logo{:href => "}
      %img{:src => "https://raw.githubusercontent.com/thoughtbot/refills/master/source/images/placeholder_logo_1.png", :alt=>"Logo Image"}
      .hero-copy
        %h1= @product
        %p
          A few reasons why this product is worth using, who it's for, and why they need it.
    %button
      Learn More

And add the associated Sass to a new hero.scss file:

views/sass/hero.scss

.hero {
  $hero-background-top: #7F99BE;
  $hero-background-bottom: #20392B;
  $hero-color: white;
  $gradient-angle: 10deg;
  $hero-image: 'https://raw.githubusercontent.com/thoughtbot/refills/master/source/images/mountains.png';

  @include background(url($hero-image), linear-gradient($gradient-angle, $hero-background-bottom, $hero-background-top), no-repeat $hero-background-top scroll);

  background-repeat: no-repeat;
  background-position: top;
  background-size: cover;
  padding-bottom: 4em;

  .hero-logo img {
    height: 3em;
    margin-bottom: 2.5em;
  }

  .hero-inner {
    @include outer-container;
    @include clearfix;
    padding: 3em;
    margin: auto;
    text-align: center;
    color: $hero-color;
    a {
      color: $hero-color;
      &:hover {
        color: darken($hero-color, 20%);
      }
    }
    .hero-copy {
      text-align: center;
      h1 {
        font-size: 1.6em;
        margin-bottom: .5em;

        @include media($large-screen) {
          font-size: 1.8em;
        }
      }

      p {
        font-family: $serif;
        margin: auto;
        margin-bottom: 3em;
        font-weight: 200;
        line-height: 1.4em;

        @include media($large-screen) {
          font-size: 1.1em;
          max-width: 40%;
        }
      }
    }
  }
}

Don’t forget to update your main.scss file to require the new Sass file:

views/sass/main.scss

@import "normalize";
@import "bourbon/bourbon";
@import "base/base";
@import "neat/neat";
@import "hero";

When you modify those files and reload the browser, you should see your page with a formatted Hero image and basic content, using all the conveniences of Bourbon. And when you check your CSS file, you’ll see that only the bits of Bourbon that were essential for this component have actually been compiled and included.

Do It Your Way

Bourbon and Sinatra feel like a perfectly matched set. Both allow you to develop your web application your way, while giving you as much or as little support as you might need. Want to incorporate jQuery? Want to add some Angular? Prefer using Backbone or some other ? This combination is still a great way to start, and it’s a decision you won’t regret as your product evolves.

Just to get you started, I’ve included the Sinatra and Bourbon code I use as a boilerplate for my own web applications on GitHub for you to clone and play with. Have fun!

M. David GreenM. David Green
View Author

I've worked as a Web Engineer, Writer, Communications Manager, and Marketing Director at companies such as Apple, Salon.com, StumbleUpon, and Moovweb. My research into the Social Science of Telecommunications at UC Berkeley, and while earning MBA in Organizational Behavior, showed me that the human instinct to network is vital enough to thrive in any medium that allows one person to connect to another.

rubyruby frameworkssasssass mixinssinatraStuR
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week