Customizing Bootstrap the Right Way

How to setup your app the right way to make upgrades simpler in the future

I’ve built dozens of web apps using Bootstrap. Countless one-pagers and plenty of full sites. In the early days I thought the framework was the cat’s meow because of how quickly you can get a decent looking webpage up and running. Then every site on web looked like the default Bootstrap template. Naturally, I graduated to configuring variables.less which felt like getting behind the wheel of a Ferrari 458 after pedaling around town in Herbie. This was my MO for a while before I tried to upgrade to a newer (minor) version of Bootstrap. The upgrade process, if you’ve modified the variables.less file to the 10th degree as I had, is terribly painful because of how quickly @mdo and the community is fixing bugs and enhancing Bootstrap. It’s simply not possible to keep an app up-to-date using the customized variables.less method.

How do you take your coffee?

Fast forward to today. I’m working on a project which leverages a completely customized version of Bootstrap 3. When I say “completely customized,” I mean completely customized. We’ve modified almost every property in variables.less and a recent upgrade to version 3.1.1 took less time than walking across the street to get a coffee. And that excludes waiting for the barista to explain the 7 different flavors you can taste in today’s special blend.

Let me show you how we do it.

Photo source.

It’s all in the setup.

To get off on the right foot, you need the Bootstrap source code. I’m using Express for my projects these days and my directory structure looks like this below. I’ve tucked away the Bootstrap LESS source code in its own folder under /public/css/less.

Directory structure. Available as a Gist on

Note the site.less and site_variables.less files in the /public/css folder. Site.less is created by default by Express (formerly style.less, I renamed it). The site_variables.less file is where the magic happens. Except it’s not really magic.

Inside /public/css/less, open bootstrap.less and add an @import statement on line #2. Ensure it is below variables.less so the overrides work later on.

// Core variables and mixins
@import “variables.less”;
@import “../site_variables.less”; //customizations
@import “mixins.less”;
// Reset
@import “normalize.less”;
@import “print.less”;

Rejoice! This is the only customization being made within Bootstrap source code.

Getting specific about the two LESS files in our setup, let’s look a bit closer at their specific purpose.

  • Site.less contains all of our site’s custom CSS selectors and rules. This isn’t anything special, just a helpful filling of your favorite markup language.
  • Site_variables.less contains Bootstrap variable overrides. We do not change /less/variables.less as suggested in the Bootstrap docs.

Taking a snapshot of our site_variables.less looks like this below. Pretty basic.

-primary: #3d9cdc;
-height: 80px;
@navbar-inverse-bg: #2a333b;

These LESS variables simply override the “brand” and “navbar-height” variables found in Bootstrap’s source during compilation because they come after in the order of operations.

Following this pattern and using a separate “variables” file allows us to move quickly between Bootstrap versions. The upgrade process involves dropping in all of the LESS source files with no conflicts except one—the @import on line #2 in bootstrap.less shown above. If any Bootstrap variables are added, our LESS still compiles. If any Bootstrap variables are removed or changed, our LESS fails to compile and tracking down the issue is as simple as looking at the console error.

I think I’ll go try this week’s Columbian blend now.