Using React with ECMAScript 2015

So you like React, and you want to tinker with it using the shiny new features of ECMAScript 2015. Here’s a little walkthrough on how to get started using them together in holy matrimony.

Since support across browsers for ES2015 varies heavily, currently the best method of getting a smooth ride across the next-gen landscape is using a transpiler. One such transpiler is Babel, which we will be using later on.

First thing’s first, let’s create a simple React component:

// hello-world.js

import React from 'react';

class HelloWorld extends React.Component {
  render() {
    return <p>Hello, world!</p>;

export default HelloWorld;

Ahhh, classes. That’s the stuff.

Now we need to render it somewhere:

// index.js

import React from 'react';
import { render } from 'react-dom';
import HelloWorld from './hello-world';

  <HelloWorld />,

As for putting all of this together, I’m going to use gulp, but you could use pretty much any other build tool known to mankind.

Install the necessary packages for building the project:

npm install --save-dev gulp browserify babelify vinyl-source-stream

You also need React:

npm install --save react react-dom

Most of these packages are probably familiar, apart perhaps from babelify; a “third party” transform that lets browserify convert source files passed to it. In this case we’re converting, or “transpiling”, from ECMAScript 2015 to good ol’ JavaScript as we know it today.

Moving on! Create a task to transpile and bundle your files:

// gulpfile.js

var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');

gulp.task('build', function () {
    entries: 'index.js',
    extensions: ['.js'],
    debug: true

gulp.task('default', ['build']);

What the bonkers just happened?!

  • Browserify traversed your dependency tree, starting with index.js
  • Transpiled source files to ES5
  • Bundled them all together into one file
  • Sent it on its merry way to the dist  directory

Don’t have the time or inclination to copy/paste the code above? Clone the (more frequently updated) repository here.

This Post Has 15 Comments

  1. Ian

    How is it that you are importing react? Are you using the raw react.js in the root of the project file?

    1. Joacim Löwgren

      It’s being installed as an npm package. That might not be entirely clear, as I’m linking to the instructions on how to install required package (0.13.0-beta.1 or later) instead of showing it myself. I’ll edit the post to clear things up.

  2. Simon Holloway

    I implemented something similar to this yesterday, and found that the build time of my scripts was looking like 10s on my windows machine (yet to try it on my linux box at work). I’m guessing this is because I’m compiling all of my node_modules every time. This makes it a bit painful when using it with something like live-reload or browser-sync.

    Have you encountered this issue also?

    P.S I really enjoy being able to type

    import foreach from ‘lodash/collections/foreach’;

    foreach([1,2,3], function (value, key) {
    console.log(key + ‘=>’ + value);

  3. Mark

    I was getting an error trying to make a component class like yours..
    Uncaught TypeError: Super expression must either be null or a function
    To fix…extends React.Component change to capital “C” on “Component”

  4. Mark

    I meant to say my editor’s auto-complete chose lower case component and it took me a while to figure out the problem. Just incase someone else does the same thing I can save them some time.

  5. Ajar

    Great post Joacim!
    I like it due to its simplicity.
    I’ve noticed in your repository you switched to webpack. why did you?
    Is there anything you couldn’t do with the current setup or you were just curious about webpack?
    I tried using it but since I’m developing on a windows machine I cannot use webpack-dev-server due to its dependency on node-gyp (which is a long time nightmare for anyone developing on a windows machine…).
    So I decided to switch to browserify / gulp / babel workflow. that’s how I got here. and your switch makes me wonder if there is anything I cannot achieve using this post’s setup?
    Because the syntax is much more friendly and intuitive. gulp eco-system is large enough to cover any additional needs so why switch?

    1. Joacim Löwgren

      Hi Ajar

      Thank you, and good question. First of all, I have nothing against Gulp. The change was simply because every project I’m involved in nowadays is using Webpack. It became sort of an obsession to convert (almost) every hobby project under my belt to use Webpack in order to get a grasp of its inner workings. While I agree that Gulp will cover most bases, and believe me I used it rigorously for a long time, I think Webpack is a more flexible build system, though also more difficult to understand and get the most out of.

  6. mike

    Hi Joachim,

    What’s the best way to render HelloWorld component? I created an index.html file and imported bundle.js. I created a div with id=’hello’ and changed document.body to document.body.getElementbyId(“hello”) but I’m still not seeing anthing. Any tips?


    1. Joacim Löwgren

      Your issue might be the casing of getElementbyId, which should be getElementById.

  7. Fess

    Howdy, Thanks for demo. I don’t see jsx files in your project. So nor class usage neither webpack. Do I miss something?

    1. Joacim Löwgren

      The jsx-files were changed to the regular js-extension as per more recent conventions. There is no need to use the class syntax for React components if you don’t need to rely on the lifecycle methods. Instead I’m using the stateless function syntax, described here.

  8. dmitry

    Thanks for the tutorial! This is the best explanation of how to use React, Babel, and Browserify together. Just a side note. With the new version of Reactjs ( I’m using 15.0.2) you have to also import ReactDom. So your imports should look like this:

    import React from ‘react’;
    import ReactDOM from ‘react-dom’;
    import HelloWorld from ‘./hello-world’;

Leave a Reply