Moving Codecademy to ES6, Webpack, and React

03/18/15

How we build our web-based learning interface

When Codecademy was born in the summer of 2011, the natural choice for a frontend stack was Backbone + jQuery. Backbone was less than a year old and widely considered the state-of-the-art framework for creating frontend applications. Combined with jQuery, one could do a lot of novel things with the web browser. In our case, we built something that helped teach millions of people how to code, interactively, for free.

Versions 1 and 2 of our learning interface: a code editor and a "Run" button

Over time, the company's mission outgrew that initial product. Teaching people programming skills that make them employable involves a lot more than simply writing code and hitting "Run"; we realized we need an interface which can adapt to different kinds of content and evolve in complexity over time to keep up with our learners' advancing skills.

We wanted the ability to present learners with arbitrary combinations of tools ("components") as they go through the steps of building an application, exploring a technology, learning a command line tool, etc. Some of the components we currently have include a code editor, a terminal, and a web browser.

Try it to learn some basics of Rails or AngularJS!

Early concepts of an interface which can switch between different stages of developing an application


Actual implementation of the interface teaching a user how to generate a Ruby on Rails model and run a database migration (WIP)

Building this warranted a rewrite, and 3 years later we were faced with more options when it came to choosing a stack. It wasn't an easy decision. Ultimately, we decided to go with React.js with a Flux-like pattern on top. We also took the opportunity to redo our build process and preemptively adopt the next version of JavaScript.

In summary, our frontend stack recently made this transition:

2011-2014 2014-2015
Backbone React
mustache JSX
jQuery much less jQuery
ECMAScript 5 ECMAScript 6
require.js webpack

React

http://facebook.github.io/react/

We chose to use React because our application is extremely view-heavy; there is lots of rendering and state change going on as a user advances through our interactive lessons. This is what React excels at. There were also things factored in such as the ability to render everything server-side (something Angular.js cannot do, for example).

The team is very happy with it so far. I think we saved weeks in the original 3-month timeline for this rewrite simply by using it. We didn't have to write repetitive boilerplate code for DOM manipulation or view/state synchronization. The amount of work React does for you out of the box is a breath of fresh air.

And it seems there's constantly new, innovative things happening in the React ecosystem like React Native and React Canvas.

ECMAScript 6

http://kangax.github.io/compat-table/es6/

We also went from simply having ES6 "on our radar" to actually embracing it. We automated a simple rewrite of our codebase from using the require.js AMD API to using the new language standard, import and export. It feels good to know we're relying on the language itself rather than continuing to build the company's product in a dying framework and syntax.

The main benefit of adopting ES6 has been developer happiness; boiled down, it's simply a new layer of sugar on top of the JavaScript everybody is already used to. It's also nice to know our codebase is a little more future-proof.

Since ES6 is a purely additive update to the language spec, it wasn't too hard to automatically migrate everything! It took me 5 or 6 days of work before we were able to deploy the new build to production.

webpack

http://webpack.github.io/docs/

None of this would have been easy or fun without webpack. Our old build process was literally a custom node.js script, an ugly pile of hacky regexes and fs calls.

Using webpack together with babeljs we've been able to stop worrying about our build process altogether; the only thing we have to maintain is a simple config file.

The other important point is that webpack is fast. The local page load time for our app went from 30-40 seconds to 2-3 seconds. AMD means you're loading every .js file separately. With webpack, updates are rebuilt in roughly 100ms and we're then only loading one file on the frontend. It was easily an order of magnitude speedup in the feedback loop, which has made for very happy engineers.

Webpack is also designed in a very modular way, so playing with new technology like Flowtype is as trivial as installing a loader for it.

Summary

Many engineering teams are going through this right now, so I want to give a simple takeaway that might help a few people make their own decisions.
Technology Why we chose to adopt it Benefits we've seen
React
  • Smaller code base
  • Fewer bugs
  • More performant app
  • Faster development
ES6
  • Have to eventually :)
  • Writing JS is more fun
Webpack
  • AMD is slow
  • Want to replace fragile, incomprehensible build process
  • Want flexibility to try out new technology
  • 10x local page load speedup compared to require.js
  • Easy to link external libraries via npm
  • Easy to integrate ES6 "transpilation"

Feel free to reach out if you have questions or want advice related to any of this. And it's worth mentioning that we're hiring, so reach out if you are interested.

Artur Sapek
Engineer, Codecademy
artur@codecademy.com