How to configure webpack for ES6, React, and Hot Module Replacement

There are a dozen or so tutorials on how to configure the webpack module bundler for ES6 and React with Hot Module Replacement, but in each one I either found something unclear, or something was out of date, so this is my attempt to provide a simple but complete soon to be out of date of course step by step guide on how to configure webpack for ES6 and React with Hot Module Replacement.

1. Interactively create a package.json file

npm init

2. Install webpack globally

npm i -g webpack

3 Install everything else

npm i --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react react react-dom webpack-dev-server

This will install:

  • babel, our transpiler for ES6

  • babel-loader, our babel webpack plugin

  • babel-preset-es2015 and babel-preset-react, a bunch of plugins babel conveniently packages up

  • react and react-dom for react goodness

  • webpack-dev-server to provide us with a lightweight express server

As npm module versions inevitably change over time, below are the versions I installed while writing this tutorial:

"babel-core": "^6.7.2",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"react": "^0.14.7",
"react-dom": "^0.14.7",
"webpack": "^1.12.14",
"webpack-dev-server": "^1.14.1"

4. Create all our files

Next, let's create the files we need. Below is how your directory/file structure should look:

/build/bundle.js -- will be generated by webpack


var path = require("path");

module.exports = {
    entry: "./src/main.js",

    output: {
        path: path.resolve(__dirname, "build"),
        filename: "bundle.js"

    module: {
        loaders: [{
            test: /\.jsx?$/,
            exclude: /node_modules/,
            loader: 'babel', 
            query: {
                 presets: ['react', 'es2015']


import React from 'react';
import {render} from 'react-dom';

class App extends React.Component {
    render () {
        return (
            <div>React with hot reloading is the cats pajamas!</div>

render(<App/>, document.getElementById('app'));


<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>Webpack, ES6, React, Hot!!</title>
    <div id="app"></div>
    <script src="bundle.js"></script>

5. Run!

Everything should be ready to roll (post in the comments below if you run into an issue), so let's get to it.

All we need to do is run the following command in our terminal:

webpack-dev-server --content-base build --hot --inline

webpack-dev-server runs our server, --content-base build is pointing out that our output lives in the build folder, and --hot --inline is the oh-so-beautiful magic that provides us with hot module reloading.

Better yet though, let's put this command in our package.json scripts so we can simply run npm start.

    "name": "webpack-es6-react-hot",
    "version": "0.0.1",
    "devDependencies": {
        "babel-core": "^6.7.2",
        "babel-loader": "^6.2.4",
        "babel-preset-es2015": "^6.6.0",
        "babel-preset-react": "^6.5.0",
        "react": "^0.14.7",
        "react-dom": "^0.14.7",
        "webpack-dev-server": "^1.14.1"
    "scripts": {
        "start": "webpack-dev-server --content-base build --hot --inline"
    "author": "ben lodge",
    "license": "MIT"

6. Load localhost:8080 in your browser

If everything is working properly, the following should appear in the console.

[HMR] Waiting for update signal from WDS...
bundle.js:605 [WDS] Hot Module Replacement enabled.

I've created a repo for this tutorial in case you run into any issues -


Questions, comments, improvements?