Compile Bootstrap into your WordPress theme for better peformance

In a new project we’re aiming to build an extremely lean and fast WordPress site which will give us ease of maintenance and plenty of power to customise it as we like.

In this post I’m hoping to show you that with a little bit of setup, you too can output much more efficient stylesheets (and javascript) for your bespoke WordPress theme.


Originally the client wanted to use Shoestrap to quickly get the project off the ground, which definitely has its advantages, but the more I looked at it the more I realised it was going to result in a lot of:

  1. CSS re-declarations, and
  2. numerous Bootstrap CSS and JS modules that we don’t need.

The Shoestrap base CSS was weighing in at over 140KB, and that’s before I even started redeclaring CSS rules to modify the default appearance.

So I decided it was a good time to muck in and get my hands dirty with compiling Bootstrap manually, whilst automating the process using Grunt (and a little Bower to speed things up).


To be able to follow along you’ll need to have Node Package Manager (npm) setup on your system, along with Grunt, Less, and Bower.

Installing these tools is beyond the scope of this tutorial, but there’s plenty of detailed how-to’s online to introduce you to these tools if they’re new to you.

As an aside, if you aren’t familiar with the tools above and just want to quickly customise what Bootstrap components are used in your theme, you can use the Bootstrap Customise tool to specify the modules you want included and just download a pre-compiled version. However in my case I want to maintain future flexibility in case I want to add in new modules or modify Bootstrap variables.

The Setup

I’m building the site using the excellent Roots Bedrock tool, but that’s a matter for another post. Here we’ll look at rolling out a minimal Grunt setup which will look after compiling our Bootstrap LESS such that we only get the modules we need and end up with a much lighter CSS download when people visit our theme.

I’ll keep the theme folder to a bare minimum for the time being, completely ignoring the actual PHP files required to drive WordPress.

  • assets/ – we’ll store javascript, images and other assets in various subfolders here
  • src/ – the src folder will contain all our own custom scripts, LESS files etc.
  • .gitignore – there’ll be a few items we won’t need to commit to our git repo
  • GruntFile.js – the core Grunt instructions – you can just create a blank file with this name for the time being
  • bower.json – our dependencies – again another blank file
  • package.json – various modules we’ll be adding for Grunt to use


We’re going to use Bower to manage our dependencies and quickly download the various libraries we’ll be using. Open up  bower.json in your editor and paste in the following.

  "name": "invisible-v5",
  "version": "0.0.1",
  "dependencies": {
    "bootstrap": "~3.0.0-rc1",
    "modernizr": "~2.6.2"
  "devDependencies": {}

Obviously we can add in more dependencies later on, but for the time being this will suffice.

Now just run bower install in your terminal and wait for bower to go and fetch all the necessary components. Bower will create a folder called “bower_components” and will store all its downloaded libraries there. Now let’s get our basic Grunt setup done.

Grunt Setup

First up we need to prep our package.json file.

  "name": "theme-name",
  "version": "0.0.1",
  "devDependencies": {
    "grunt": "~0.4.5",
    "grunt-contrib-less": "~0.11.1",
    "grunt-contrib-watch": "~0.6.1",
    "jshint": "~2.5.1",
    "grunt-contrib-jshint": "~0.10.0"

Note that you could just set this up with grunt as the only dependency and then later on run npm install grunt-contrib-less --save-dev and this will automatically update the package.json file, but for the time being you can just copy and paste the above into package.json as this covers everything we’ll need for this tutorial.

Next we need to install the packages.

Run npm install in your terminal and wait whilst npm does its thing. This will create another folder in your theme root, called node_modules.

Building our Grunt tasks

We’ll drive everything we need with an extremely simple GruntFile.js.

module.exports = function(grunt) {

	// Initialise Grunt

		// Core LESS compiling
		less: {
			development: {
				options: {
					paths: ["./src/less"],
					cleancss: true,
					compress: true,
					strictImports: true
				files: {
					"./style.css": "./src/less/style.less"

		// ensures that any basic javascript syntax errors are picked up before compiling
		jshint: {
		  // define the files to lint
		  files: ['GruntFile.js', 'src/js/*.js'],
		  // configure JSHint (documented at
		  options: {
			  // more options here if you want to override JSHint defaults
			globals: {
			  jQuery: true,
			  console: true,
			  module: true

		// Our main watch task - keeping an eye on files and folders and compiling them on any changes
		watch: {
			files: ["./src/less/*", "./bower_components/bootstrap/less/*"],
			tasks: ["jshint","less"]

	// Load the various grunt libraries needed

What’s happening here

So all the magic happens inside grunt.initConfig.

First up we’re defining our LESS task. Essentially we’re telling it to look at the src/less folder, and when run to clean the css and compress it. Then we tell it where to export our compiled CSS – which is the more familiar style.css file that WordPress looks for when loading the theme. You can see all of the options that can be defined for this task on the grunt-contrib-less page.

Next we’re defining a very simple jshint task, just to make sure we don’t have any GruntFile.js errors. This task can also be used later when you’re compiling your custom javascript.

Second to last we’re preparing our watch task. This task will watch our various LESS folders for changes and if any changes are saved, then it will automatically run the jshint and less tasks in that order. This way we check there’s no errors, then compile our LESS code into a usable style.css file. This saves us from having to remember to run the less compiler every time we make a less change.

Note that in the watch task I’m also telling it to watch the bower_components folder for changes – this is just in case we make a change to bower_components/bootstrap/less/bootstrap.less. Changing a vendor file?! Yeah I know, sadly I can’t find another way to modify the components that are being compiled in, but more on that in a little while.

Finally we’re using grunt.loadNpmTasks to make sure that Grunt is loading the necessary libraries for it to work. If you miss these lines Grunt will throw an error warning you that the necessary libraries are missing.

A note on .gitignore

So we’ve downloaded a bunch of vendor libraries, but we really don’t need to include those in our git repo. If we’re working in tandem with other developers, then when they pull down the repo they’ll just need to run bower install and npm install and they’ll separately pull down everything they need.

So open up your .gitignore file and add the following lines:


Preparing our LESS

Ok, we’re getting there. It may seem like a lot of setup, but remember the 6 P’s – Proper Preparation Prevents Piss Poor Performance! By spending a little time setting this up at the start, you’re going to save a lot of time in the long run, and end up with a faster loading website.

So, let’s get into some actual site code now. In our src folder create a less folder and put two files into it.


Actually you’ll be able to set this up as you feel fit. It will ultimately be beneficial to break things down further and @import each LESS file, keeping your code tidy and saving you from scrolling through a giant file with hundreds of style declarations.

Now open up style.less and add the following:

Theme Name:    My Awesome Theme
Theme URI:
Description:   Custom Bootstrap Theme
Author:        Awesome Developer
Author URI:
Version:       0.0.1

// Import the core bootstrap modules
@import '../../bower_components/bootstrap/less/bootstrap.less';

// Custom Variables
@import './variables.less';

Ok, so here we’re setting up a standard WordPress theme declaration, but note that in order to stop LESS removing the comment at the start we’re adding an exclamation mark /*!.

Next up we’re importing our bootstrap.less file which, in turn will import all the bootstrap modules. After that we’re importing our own variables.less file in which we can overrule default variables set in Bootstrap.

Importing only the components you need

As mentioned earlier, the odds are that you don’t need every component that Bootstrap offers, so open up bower_components/bootstrap/less/bootstrap.less and comment out any @import rules that you don’t need. Not ideal to be editing the source of a vendor file, but I can’t find another way to go about this. I guess you could make a copy of this file and edit it as needed though – I’ll leave that to you.

Ok, so now we’re cooking and we’re all set to start coding our styles.

Putting it all together

Now jump back to your terminal and run grunt watch. Grunt will now start watching your src/less folder for any changes.

Add some new style declarations, hit save and watch your terminal compile your styles to a new style.css file in your theme folder! Now you can make changes as needed, add variables to overrule Bootstrap defaults, and know that you’ll have a nicely minified and clean CSS file powering your theme.

That’s it, you’re ready to start writing your bespoke theme!

Expanding your tasks

There’s a huge amount you can do with Grunt, and I recommend reading up the Grunt “Getting Started” guide and reviewing the “Sample Gruntfile” to get a better feeling for what you can do with it.

You’ll be able to set up Grunt to look after your javascript in a similar fashion to the LESS, but you’ll take a variety of scripts, concatenate them, minify/uglify them, and output them to a single js file which your theme loads using the wp_enqueue_script function.

Further you can also add your theme background images, sprites, etc into your source folder, and when running a grunt build task have them copied to your assets folder and use grunt-contrib-imagemin to automatically optimise those images to be as small as possible – further saving precious kilobyte downloads!

Keeping your production server clean

If we want to keep our final production server clean so that the src folder isn’t being deployed, there does appear to be a method to making sure that the src folder is included on your development branch, but not included in the master branch which you deploy to your production server.

Have a read of this article “HOWTO: Gitignore for different Branches“. It describes exactly this. Of course it’s not a major issue to have that source folder deployed to production as it won’t be called by any of your WordPress theme files.

I hope you’ve found this tutorial useful, and any questions or suggestions are welcome in the comments below. I’m pretty new to Grunt, so undoubtedly there are refinements that can be made, but I think this gives a pretty good run through of one approach you can take to compiling a custom Bootstrap setup for your WordPress theme.