5
Published Apr 14, 2017

Elm vs. React: Development and Performance

Elm vs. React: Development and Performance

Today we’ll be comparing two component rendering frameworks, Elm and React. For this comparison, I built the same SPA (single page application) in both Elm and React/JavaScript. It’s not totally realistic, but to make things fair, I limited the application to only things React and JavaScript can both do without any other framework or libraries.

We're going to look at:

  • setup and installation
  • the feedback loop during development
  • performance
  • the ecosystems of packages
  • integration into existing codebases

The app we’re using for the comparison shows a grid of restaurants and loads more as you scroll. When you click on one, it gets added to a wishlist. This demonstrates rendering performance and how data flow works between multiple components. It was also large enough to show differences in the feedback loop during development.

Which is Easier To Get Started With?

Elm and React both give you the opportunity to try them out in the browser, so you can learn their syntax and how they work immediately. React's version of "try it out" is simpler, while Elm's version is a full-page code editor which has multiple examples demonstrating the syntax, how to work with buttons, how to do drag & drop, and some basic HTML5 Canvas examples. While React's version does show the compiled JavaScript code, Elm gets a point in its favor because the examples are better and the editor allows free-form code to be written. There is also a new online editor for Elm called Ellie that makes it even easier to try out right in the web browser.

Both Elm and React are installed using NPM, the Node Package Manager. Elm is globally installed and provides its own package manager. The default install of Elm includes the core libraries, HTML libraries and the Virtual DOM rendering engine. The default install of React includes React and the React-DOM library.

The React tutorial suggests installing create-react-app, which is a way to get React up and running quickly. It does not include Webpack or any other build tool, but it does let you use JSX syntax, ES6 JavaScript, and the Flow type-checker. Type-checking is built right into the Elm compiler.

Elm and React are easy to install and both have made efforts to keep things as simple as possible. React gets a point here with its officially endorsed create-react-app boilerplate project (though there are boilerplate starter projects out there for Elm, too).

The Development Feedback Loop

While developing the app, I found React's starter kit nice to work with because it made the feedback loop fast. The JavaScript code was recompiled whenever a change was made and the browser reloaded the web page. Elm's equivalent is elm-reactor which also watches Elm files, recompiles and reloads the web browser.

What give Elm an edge over React are the compiler error messages. While Elm has better type-checking, and React does not have any built-in type-checking (aside from rudimentary component properties type-checking), comparing the error messages is another part of the feedback loop.

Performance: Is Elm Faster Than React?

We tested React and Elm with the performance benchmark that the Elm developers used in the article Blazing Fast HTML.

Blazing Fast HTML Benchmark

We ran the benchmark with React 15.3.1, Angular 2 and Elm 0.17 selected.

Here are the results:

elm-vs-react-vs-angular-vs-ember-benchmarks

The benchmark is a to-do list web app where items are added and then removed in rapid succession. React is the slowest of the bunch at 4.875 seconds; Angular 2 is at 3.358 seconds, and Elm 0.17 clocked in at 2.964 seconds. These are the optimized versions for each library, and you can compare the code yourself to see just what optimizations have been made.

Packages and Libraries

Another point of comparison is the number of packages and libraries available for Elm and React. We should also do a comparison of some of the documentation and the general quality of the libraries.

React

React, being more popular at this time, has a wealth of packages and libraries available. It doesn’t match the number of jQuery plugins out there, but it's getting there. The idea of composable components that have a one-way data flow is so intuitive, and React is so easy to get into; it’s not hard to see why there are so many new libraries out there, with cool new user interface components being created and released daily.

Elm

Elm's advantage right now in terms of libraries is that the people writing them are early adopters who have experience with functional programming and type-checking. Being used to the paradigm, they can write higher quality code. The other advantage is that the number of choices you have to make is smaller.

Because Elm allows type declarations, all packages come with a basic set of API documentation based on all the type declarations for types, records and functions.

Another advantage is that some of the major React packages are included within Elm's core; such as Redux, Flux, Nuclear.js and Immutable.js. There's no need to search for a reactive flow library or immutable objects library when the Elm language includes those features by default.

However, when we do an apples-to-apples comparison with React, we find Elm falling short. Generally, we shouldn't judge the merit of a language or framework based on how many packages and modules there are, or based on popularity, but the simple fact is that React is popular, and with more developers there are more bug reports and fixes to the packages and more momentum in driving different modules and libraries to be developed.

Integrating Elm or React Into Existing Code

React

React has only one way of being integrated into a code base: it can only replace DOM nodes. This is great because it keeps things simple, and when you're working on integrating React into an existing code base, all you need to worry about is passing data from the rest of the web app into the React components.

All the other nice things about React, like using Redux, Nuclear.js, Immutable.js and ReactRouter, can be integrated later on. React is only one part of the framework and it can function as a replacement for the view rendering of any other framework. You don't even have to use the JSX syntax! You can start using React in an existing web app by including the React and ReactDOM scripts and with a few lines of JavaScript you can define and insert a React component into the page.

Elm

Elm has three different ways to embed components and applications: fullscreen, embedded and worker. Fullscreen replaces the page with the Elm app, great for writing web-based games. Embedded mode functions in the same way as React: it renders into a particular DOM node. Worker lets you use the Elm component inside of a web worker, as a background process that works with the rest of your app.

To communicate with JavaScript code, you can pass things into Elm with flags for one-way communication (similar to passing properties into a React component), or you can use subscriptions to listen for events from the Elm component, such as mouse clicks or text input changes (similar to event callbacks in React). When we limit the comparison between Elm and React to React's mode of integration, Elm is a bit more complicated in terms of having to set up flags and subscriptions but once you get used to it, it's about as easy as React.

What could give Elm an edge over React is the compilation and bundling. You can compile multiple Elm components into one bundle and then include a script tag and an initialization script, and voila: you now have access to all of your Elm components in a nice convenient package. Because it is built into Elm, you don't have to rely on Grunt, Gulp, Webpack, SystemJS or whatever flavor of module bundler and build system is popular today. However, since you have to learn Elm as well, it can be a hard sell to integrate it into an existing code base.

Conclusion: And The Winner Is...

Here's how Elm and React compare:

Setup and Installation: It's a tie

  • Elm can be installed using NPM (Node Package Manager) and it has its own package manager to make it simple to add more packages. There are Elm syntax highlighters for the popular text editors and IDEs.
  • React can be installed using NPM and it doesn't need anything else. You can start using it immediately.

Development Feedback Loop: Elm wins

  • Elm wins because of elm-reactor, a built-in way to create and test Elm components and applications rapidly
  • React loses because it requires a transpiler for ES6, a transpiler for JSX, and it also requires webpack to tie it all together, which is a lot of setup just to get the development feedback loop started.

Packages and Libraries: React wins

  • Elm doesn't have as many packages as React, and because Elm itself hasn't released a stable version 1.0, the underlying architecture of libraries could change with every new release.
  • React wins because it has a large number of libraries, and many more components have been written with it due to Facebook's popularity.

Integration into Existing Code: React wins

  • Elm almost wins because it has three different ways to integrate components, and all your components can be compiled into one JavaScript bundle, making it easy for you to grow your Elm web app inside of the existing code base.
  • React wins because it is very easy to add a CDN link to load React and ReactDOM,then render your component; you can even use the JSXTransformer in the browser. Also, react is just plain JavaScript, making it easier for your friends, colleagues and coworkers to pick it up and use it.

Ultimately, both frameworks are really useful, but they have different strengths. I hope our comparison here can help you choose which one is right for you.