Customizing Bootstrap with gulp.js and Bower

How to setup the web project that uses custom-themed Bootstrap front-end framework.


Twitter Bootstrap is a very popular front-end framework that supplies a set of styled components, responsive CSS grid as well as a bunch of JavaScript plugins that allows you to rapidly kickstart your new web project. Bootstrap components look fancy by default but in case you want them to fit your own vision of great design, Bootstrap gives you an ability to customize it.

The easiest way is to override the desired styles with your own CSS file included after the original one. Not a very pretty solution but quite convenient in some cases.

The second one is to use official customizing tool that allows you to create your version of the Bootstrap build. This approach, in turn, gives you clean sources but every time you decide to change something, you have to download the new build, which is quite tedious.

The third option, the most acceptable as for me, is to take advantage of LESS sources of the Bootstrap, customize them and compile. Of course, this approach requires some environment setup. How to achieve this I am going to tell you in this small article.

File Structure

You could choose the project structure as you wish, but in this guide I would use the following one:

|-- less
| `-- bootstrap
| `-- variables.less
|-- public
| |-- lib
| | `-- bootstrap
| | |-- dist
| | | |-- css
| | | | `-- bootstrap.css
| | | |-- fonts
| | | `-- js
| | `-- less
| `-- index.html
|-- gulpfile.js
|-- bower.json
`-- package.json
  • less — your LESS sources including custom Bootstrap variables definition (bootstrap/variables.less)
  • public — you main front-end code. This directory should be served by the web server.
    - lib — libraries code
    - lib/bootstrap/dist — compiled and ready to use Bootstrap code
    - lib/bootstrap/less — LESS sources of bootstrap

Project setup

All we are going to do is just compiling the Bootstrap’s LESS files against our own custom variables.less file and automating the build process so that it reassembles the new resulting CSS file whenever we make some changes in variables.less.

The main tools we would use are gulp.js and Bower. I assume that you already have them installed, if not, follow the installation guides on their official websites.

So first of all, we should create the project directory and initialize the package.json and bower.json descriptors for that.

> mkdir custom-bootstrap-kickstart
> npm init
...
> bower init
...

Couple of questions about your package details and you’ve done.

As it was mentioned above, we would use Bower as a package manager. So we need to install Bootstrap as a Bower dependency.

> bower install --save bootstrap

As a result, we will get the whole content of Bootstrap’s GitHub repository in the bower_components directory. We don’t need all that files, but only ready to use JavaScript files (dist/js), fonts (dist/fonts) and LESS sources of Bootstrap (less folder). So we will move that files into our lib/bootstrap folder. The gulp.js and main-bower-files package could be helpful in this task, so we need to install them first:

> npm install --save-dev gulp main-bower-files

Now it’s time to create our first gulp task, that would actually copy abovementioned files into our public/lib directory. Let’s create the gulpfile.js in the root dir of the project and define our task inside:

var gulp = require('gulp');
var mainBowerFiles = require('main-bower-files');
gulp.task('bower', function() {
return gulp.src(mainBowerFiles(), {
base: 'bower_components'
})
.pipe(gulp.dest('public/lib'));
});

Note: passing { base: ‘bower_components’ } as a second argument to the gulp.src() is required. See this SO thread.

This task builds a stream with all files defined in the main property of the dependencies’ bower.json and copies it to public/lib folder. Here is what we would get for Bootstrap:

"main": [
"./dist/css/bootstrap.css",
"./dist/js/bootstrap.js",
"./dist/fonts/glyphicons-halflings-regular.eot",
"./dist/fonts/glyphicons-halflings-regular.svg",
"./dist/fonts/glyphicons-halflings-regular.ttf",
"./dist/fonts/glyphicons-halflings-regular.woff"
]

But since we are going to compile the LESS sources into CSS file by ourselves we need to slightly override this behavior. main-bower-files utility enables us to achieve that by adding the custom property “overrides” to our bower.json file so that we could redefine the “main” property of the Bootstrap:

"overrides": {
"bootstrap": {
"main": [
"less/!(variables).less", "dist/fonts/*", "dist/js/*"
]
}
}

All the LESS sources except variables.less would be copied to the lib directory now, so it only remains to put there our custom variables.less (you could take one from the original Bootstrap sources and modify as needed) and compile the sources (use gulp-less plugin for that). We would introduce two concise tasks for that:

gulp.task('bootstrap:prepareLess', ['bower'], function() {
return gulp.src('less/bootstrap/variables.less')
.pipe(gulp.dest('public/lib/bootstrap/less'));
});
gulp.task('bootstrap:compileLess', ['bootstrap:prepareLess'], function() {
return gulp.src('public/lib/bootstrap/less/bootstrap.less')
.pipe(less())
.pipe(gulp.dest('public/lib/bootstrap/dist/css'));
});

Now after running:

> gulp bootstrap:compileLess

we will get the compiled custom version of bootstrap.css in the public/lib/bootstrap/dist/css directory. The finishing touch would be implementing triggering the whole build process whenever some changes in variables.less introduced. Let’s create a watch task for this:

gulp.task('watch', function() {
gulp.watch(['less/bootstrap/variables.less'],
['bootstrap:compileLess']);
});

Run

> gulp watch

to start watching on changes, the result bootstrap.css would be compiled automatically if you have done any.

Example of the project could be found on GitHub.

That’s all! Happy hacking!

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.