Using CoffeeScript and SASS with Sinatra

by Andrew Stewart
published October 26, 2012

Most of my newer projects tend to be smaller projects where I don’t want to have the massive overhead that Rails brings with it, or what I’m trying to build doesn’t necessarily fit the Rails use case.

But I’d still like at least some of the benefits of the Asset Pipeline, namely being able to use SASS/SCSS in place of CSS, and using CoffeeScript to write my app’s Javascript.

To do this, I’m using the sass gem’s Sass::Plugin::Rack functionality, and the rack-coffee gem.

How

First, add them both to your Gemfile:

Gemfile
source :rubygems

gem 'sinatra'

gem 'sass'
gem 'rack-coffee'

Then bundle install.

Then add the hooks into config.ru:

config.ru
require 'rubygems'
require 'bundler'
Bundler.require(:default)
require 'sass/plugin/rack'
require './myapp'

# use scss for stylesheets
Sass::Plugin.options[:style] = :compressed
use Sass::Plugin::Rack

# use coffeescript for javascript
use Rack::Coffee, root: 'public', urls: '/javascripts'

run MyApp

So now you can put your stylesheets into the public/stylesheets/sass/ folder, and they will be automatically compiled to CSS when changes are made.

You can put either CoffeeScript or regular Javascript files in public/javascripts/ and they will be available in your app’s layout.

Example

For an example app with a directory structure like this:

.
├── Gemfile
├── config.ru
├── myapp.rb
├── public
│   ├── javascripts
│   │   └── script.coffee
│   └── stylesheets
│       └── sass
│           └── style.sass
└── views
    ├── layout.haml
    └── index.haml

In layout.haml you might have something like this:

views/layout.haml
!!! 5
%html
  %head
    %title MyApp
    %link{rel: 'stylesheet', href: '/stylesheets/style.css'}
  %body
    .container= yield

    %script{src: "/javascripts/script.js"}

There are also a few alternatives, and sprockets can be rigged to work with Sinatra apps, but this is the solution that works for me. It also helps to supply a long cache lifetime for stylesheets and scripts if you’re using this method.