Using Webpack and React with Jekyll

Alli Zadrozny
May 2, 2016 · 8 min read

This is a supporting technical post for my talk coming up this Saturday at Jekyll Conf — the free online conference for all things Jekyll. I’ll be speaking about Elasticsearch for Jekyll. In order for our users to interact with an Elasticsearch cluster, we’ll be using webpack so we can tap into searchkit’s amazing components for our UI. This is the first step in the process to use searchkit on Jekyll. See the original post on my blog here.

updated Sept. 18th, 2017 to include support for GitHub Pages

Jekyll is great, and I’m a fan. It’s been around for a long time and remains a straightforward and simple solution to creating a static blog — in fact, I use it for my own blog, and we use it over at One More Cloud for serving all of our static content. However, there are some more interactive pieces I’ve wanted to add to our sites (including search) that require some fancier UI code but don’t necessitate a more powerful site generator. Enter Webpack and npm, which gives me access to node modules that were previously something I’d only look at wistfully. I find trying to let Jekyll handle javascripts annoying and tedious, so I like that with this I’m able to use an ecosystem that is specifically designed to do major lifting in compilation, testing, and minification.

You can view my Jekyll-Webpack boilerplate on Github, made for this post:


This is a very simple implementation and doesn’t rely on weird code acrobatics. I write my tutorials assuming people have shallow knowledge of the tools I use so that beginners may benefit from the extra explanation — more experienced devs should feel free to skim. In this post, however, I’m assuming readers have some experience with Jekyll. I’ll walk through how to create a basic jekyll-webpack integration, and then use it to create a simple React component.

Integrating Jekyll and Webpack

Pre-work: Setting up your dev environment

We’re not using anything beyond Jekyll, Webpack, and Node’s package manager. Install all three with the most current versions.
- Install npm: $ sudo install npm -g
Make sure you have the latest version of npm, which at time of writing is 3. This prevents installing multiple copies of dependencies in your node_modules directory and significantly reduces npm’s footprint.
- Install webpack: $ npm install webpack -g
- Install jekyll: $ gem install jekyll -g

Now that we have everything ready to use, let’s get started!

1. Rearrange your project structure

Note: Using GH pages to deploy? Skip this step and move on to Step #2!

$ jekyll new [project-name] scaffolds all partial files in the root. I like using a src/ (or, source) and public/ directory to organize my Jekyll projects, especially when using Jekyll with other frameworks. Here’s the difference:

generic jekyll scaffold:

A base example of what we’ll use:

This requires that you move all of the content you want Jekyll to pick up for the build process to a src directory in the root, including the index.html. Keep the config.yml in the root. You’ll need to let Jekyll know you’re building from src into public, so, in your config file, give it some pointers:

Because you’re building to a public folder, you can use Pow to serve the static site at, which I find nice for development.

2. Add package.json

npm won’t install your modules unless it can find a package.json in your root with a recognizable object (i.e. the file cannot be blank). Create the file with $ touch package.json and add an empty json object with $ echo {} >> package.json. Or, your can let npm create the package.json for you by running $ npm init in the root, which will walk you through a setup in the terminal and then generate a populated package.json. Mine looks something like this:

3. Add Webpack folder

Create a webpack/ directory in the root project with an entry.js file. This folder is for development only. We’re keeping it out of the src directory because we’re going to configure Webpack to pick up entry.js and write a compiled version into the src files for Jekyll. Jekyll will then pick it up and serve it statically with the rest of the site.

Also, remove any Jekyll javascript files from your assets directory. Keep that javascripts folder in the assets folder, though — we’re going to use it!

4. Configure webpack

Create a webpack.config.js in the root. In the config.js, I’ve laid out where webpack can find entry.js and where I want it to compile to:

Notice that the output.path is within the src/ directory.

5. Ignore all the things!

You’ll absolutely need to tell both github and Jekyll to ignore node_modules/. I forgot to do this at first, and Jekyll was taking ~30–28s to generate because of the ridiculous amounts of node_module files. This was also pre-node 3, which meant dependencies were loading multiple copies of their own dependencies. It was dependencies all the way down, with a 208MB mark at first. Lesson: don’t use npm 2.

In your .gitignore, add src/assets/bundle.js, public, and node_modules. Since bundle.js is just a compiled version of of entry.js there’s no reason to version it, and same idea with public. It’s expected with using npm to always ignore the modules directory so that pushing and pulling doesn’t take up a ton of bandwidth.

if using Github pages for deployment:

Tell Jekyll to ignore node_modules when building in your config.yml:

6. Include your bundle.js in your html

In your _layouts/default.html, add your compiled bundle.js file.

If you’re using the jekyll-assets gem:

7. Install dependencies

I like writing my javascript in ES6, so let’s install the loaders and libraries we’ll need to compile and run the es6 React we’ll write in the next step.


The save-dev flag will write the packages to the package.json devDependencies. Now your package.json should look something like this:

8. Add some test javascript to entry.js

Just to test everything is working correctly once we build, add something like console.log("Hello, world!") to your entry.js.

9. Build your site!

First, run $ webpack to generate the new bundle.js from entry.js. If you don’t do this, Jekyll won’t have a bundle.js to pick up and reference in default.html. Next, run $ jekyll build to build your site. Open up your dev site, pop open the console, and double check that your statement was logged. If not, there’s something amiss, so double check your config files and the paths you’ve set for webpack. If things are working, excellent! Move on to Step 10 and let’s get to writing some React!

10. Create a React Component

The nice thing about having a webpack directory is now we can organize our components in a new folder and import the things we need in entry.js in a modular way. Create a components/ folder inside our webpack directory, and create a new file called Hello.js.

In Hello.js, create a simple static component:

In entry.js load react and import your component:

10. Mount your component!

Add the div React will render your component in your default.html (or wherever you please):

*If you’re not using jekyll assets, you’ll hard-code the javascript script path instead of using the liquid tag like so:

11. Rerun your build and see your component!

Run $ webpack to compile your js and $ jekyll build so Jekyll will catch the newly compiled file. You should now be able to see a lovely React component on your Jekyll page!

In Closing

This should work fairly easily, so if you have any troubles with it please let me know! I’m happy to help. The annoying part is constantly having to run webpack after making changes, but you can keep Jekyll watching changes to bundle.js with $ jekyll build -w AND webpack watching with $ webpack -w. This way, moving back and forth to the terminal is minimal.

The boilerplate is up on Github here:

If you’re using Github Pages, please see this branch:

Image for post
Image for post
Now you’re one of the cool kids.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store