A drawing of a glass of bourbon and glasses, representing the logos of the two projects discussed in this post, Bourbon and Sass.

Sass with Bourbon on Node

I've been using Sass for a few years now, thanks to Chris Coyier's great article on CSS-Tricks, Sass vs. LESS. I think it is great, especially for large-scale web projects with complicated stylesheets. I'll let you read Chris's article for all of the benefits, and focus on how to get Sass, and my favorite Sass framework running in a Node environment.

Introduction

The Sass compiler is written in Ruby, which is great unless you don't already have Ruby installed. If you've ready my other blog post, 'Ridgeline', you'll know that I try to make my development environment as stack-agnostic as possible, meaning whatever technology stack my client is using, my code can fit in seamlessly. I don't want to make a client add an entire new language to their stack, just to use my code, so relying on the Ruby engine is a no-go for me.

Luckily, the project 'libSass' was started a few years ago, which is a C/C++ port of the Sass engine. It's fast (faster than the original Ruby version), and has wrappers for most server-side langages (including Ruby itself). By using libSass, I can ensure that whatever stack my client is using, there is a libSass wrapper for them, and (hopefully) my code can easily be added to their project.

The problem, of course, is that the original Ruby engine is the "offical" compiler, and libSass is usually a few features behind. To further complicate things, the Sass framework that I was using at the time, Compass, has compatibility issues with node-sass and couldn't be used. As I found out, getting the right combination of Node, node-sass, and a functional Sass framework is a delicate task.

The first try

After starting with an early version of my Ridgeline development environment, I set out finding the right npm packages. "gulp-sass" is the Gulp plugin that brings Sass compilation to your Gulpfile. It has "node-sass" (the NodeJS wrapper for libSass) as a dependency, and allows you to add sass compilation to your Gulp tasks, as opposed to adding it to your server's middleware. This works with Ridgeline's philosophy, and generates static CSS files in case a client needs them.

After setting up my gulpfile with "gulp-sass" and a few other plugins, I quickly found the first dependency problem. There are two major versions of Sass out there: the original Ruby Sass compiler, and the libSass project, which is a port of the original compiler to C/C++. The problem is that libSass is a few version behind; not supporting any 3.3 features, and missing a few 3.2 features.

I had to find the problematic lines in my existing Sass code and remove them. In addition to that, the Sass framework, Compass, didn't work at all with node-sass. Compass is built on Sass, and includes a bunch of handy mixins for CSS3 compatibility and other helpers to keep your Sass files clean. It is also relies on some Ruby code to add additional features too complicated to write in just Sass syntax, and therefore is completely incompatible with node-sass.

Moving to Ruby

Well, as luck would have it, there exist "gulp-ruby-sass" and "gulp-compass" plugins, which use the Ruby compiler instead of the libSass compiler. Switching out "gulp-sass" with "gulp-compass" was easy enough, and let me run all my old Sass files, with or without Compass. It still didn't feel "clean" to be using Ruby just to get a pre-processor to work, and didn't fir with Ridgeline's goals. That is when I found "Bourbon".

Back to Node-Sass and switching to Bourbon

Since the CSS3 mixins are a huge time saver for me, I had to find some other framework to use in Compass's place.

Enter Bourbon. Bourbon is a minimal Sass framework providing CSS3-related functions and other helpers, but leaving out Compass's layout generators and functions that. As a designer, I'd rather implement layouts on my own, which made Boubon more attractive philosophically anyway. Unlike Compass, it is written entirely in Sass, and compatible with libSass (almost). It can also be installed with Bower, along with all my other JS and CSS libraries. New goal: stick to node-sass, switch to Bourbon, and I should be golden.

Of course, it was not going to be that easy. The most recent version of Bourbon at the time (4.0.0-rc1) used Sass 3.3 features, even though they claim to only require 3.2 (you get a bunch of errors when trying to compile the Sass code). After some time problem solving, I ended up modifying the problem files in Bourbon 4, and got everything running for a third time. Of course, this was an absurd solution, because upgrading Bourbon in the future would be a hassle. I tried using the older Bourbon 3.2, but I still ran into some compatibility issues. There was some talk around the web about making a separate branch of Bourbon 3.2 that was compatible with libSass, but nothing was going to happen immediately.

The solution is found

Looking through NPM for solutions, I came across "node-bourbon". I had originally passed it off because it hadn't been updated in months and I wasn't sure exactly which version of Bourbon it was running. I also didn't like the idea of using NPM just to download a handful of .scss files, not really related to Node. At this point, a 7-month-old version of bourbon seemed like my best bet, so I installed it, ran some tests, and it seemed to be feature feature-comparable to the current Bourbon docs. phew.

Conclusion:

The final solution that I came to for running Sass with Node is not ideal. I don't know exactly which version of Bourbon I am running (Bourbon 3.2 didn't work when I tried it), and I can't use all the Sass 3.3 features (mainly @extends). When Bourbon 4 is released, I will probably be missing some nice stuff, and eventually I may have to worry about compatibility with other libraries surrounding Bourbon (Neat, Bitters, Refills), but for now things seem to be running fine.

A blog post by someone who reached out to the current maintainer of libSass gives hope that libSass may be caught up to Sass 3.3 by mid-summer 2014, but that never actually happened. At least the setup I created has as few language dependencies as possible, doesn't require modifying library files, and has the possiblility of running the lastest versions of Bourbon someday.