Elm vs. React: Development and Performance

Published Apr 14, 2017
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.

Discover and read more posts from Rudolf Olah
get started
Enjoy this post?

Leave a like and comment for Rudolf

12
4
4Replies
Erik Engi
4 months ago

Hi all, to improve on the setup time with React I can highly recommend you Razzle along with my Razzle Material UI Styled Example.

Laszlo Marai
6 months ago

Meh, no offense, but I really feel these comparison posts are written with the end result in mind: at the end you have to state that there isn’t any difference.

One specific flaw I found in yours is that you say that Elm wins with the development feedback loop, but the explanation really talks about the setup time. I.e. the time it takes to set up the build. While this may be important, it’s a different issue. One could have a longer setup time and then a tighter feedback loop, which could pay in the long run. (Here, we didn’t learn about the feedback loop really, or if we did, then my understanding is that they are identical.)

Rudolf Olah
5 months ago

No offense taken! Your comment is really valuable to improve my writing/editing.

I agree that at the end, I have to state essentially “depending on these factors, pick what is right for you”. Especially in this early stage where we’re only starting to see what happens to larger React codebases and are starting to see Elm codebases that are growing.

To address your other comment: setting up the build impacts the feedback loop but you’re right they are orthogonal, you could have a long setup time and a quicker feedback loop. What I found with Elm is that the setup time is short and the feedback loop is also tighter.

The feedback loop for Elm is elm-reactor which watches/rebuilds the Elm files. For react it would be webpack/react-starter-app. So yes, they’re identical in that respect, however I would give a lot of weight to anything that moves away from over-complicated/magic webpack configuration. I’ve had coworkers talk about using Rollup.js, SystemJS and other non-webpack tools.

The feedback loop with Elm felt faster. Even on a really good setup of a React or Angular project that uses webpack bundling and the webpack dev server and watch/rebuild, it still felt faster to iterate with Elm and that’s due to the language itself. But here we’re venturing into very very subjective territory.

Vishal Shekar
6 months ago

Thanks

Show more replies