Elm is a delightful language that helps make web applications more reliable by eliminating runtime exceptions. I find it extremely productive working with Elm, and would like to be able to use it in a JavaScript codebase without breaking the existing application or having to rewrite it altogether. However, it’s not obvious how to try out Elm in a small piece of the application, just enough to evaluate how well it works. This is what we will address in this article by exploring how to add a new feature to a React codebase with Elm.

We’re going to start by bootstrapping a new React application using create-react-app.

Once this is done, enter the newly created directory and run:

yarn start.

Your app should open in a browser and you should see a screen like this once everything is successfully set up:

Screen Shot 2017-05-24 at 10.18.52 AM

Embedding Elm code as React components

With our React codebase in place, let’s see how we can add a new feature with Elm. The classic Elm Hello World application is a counter whose number increases or decreases when we press a + or - button respectively. This is the feature we’ll be adding to the React codebase.

Let’s create our Elm file in the src directory and call it Buttons.elm. Add the following content to the file:

To be able to embed Elm in React, we will compile the Elm file to JavaScript first, then work with the generated JavaScript code.

elm-make src/Buttons.elm --output src/Buttons.js

You will see a prompt that some new packages are needed. These are the elm packages needed to run our Elm file. Accept the prompt and proceed.

To make the connection between the generated code and React, we will use the react-elm-components package. Let’s go ahead and install it:

yarn add react-elm-components

Once the install is complete, it is simple and straightforward to embed the generated JavaScript. Here’s how we can embed it in our src/App.js file:

However, once we try to run the app again, we’ll start get linting errors since the linter will try to catch errors in the generated Buttons.js file. If you try running the app at this point, you’ll see a screen like this:

Screen Shot 2017-05-24 at 10.51.22 AM


This is easily fixable by telling ​​eslint to ignore linting the generated file. Add the line  /* eslint-disable */ to the top of the Buttons.js file and you should be good to go!

Here’s the final result of React and Elm working together seamlessly 🎉

Screen Shot 2017-05-24 at 11.06.25 AM

Bundling with Webpack

The same result can be achieved by setting up webpack so that you are able to require the Elm components directly, rather than having to do the compiling step yourself.  This way you can write code like this:

import { Main } from './Buttons.elm'

and webpack would take care of compiling Elm to JS. This needs a bit more setup but its a much better approach.

I recommend checking out the example project from the react-elm-components repository, which shows a more complete example with webpack included.


With the help of  react-elm-components it is very simple to introduce Elm to an existing React application. When experimenting with a new language such as Elm, the best approach is to try it out in a small part of the codebase first, such as adding a new component, then evaluating whether it works for you.  I tried it out with a few small components on an existing React app, and I liked how it turned out, so I continued porting more components to Elm. Try it out, and experience it for yourself. I’ll leave you with this quote from the react-elm-components page:

Companies that use Elm in production usually start with a single component. So if you want to use Elm at work, start with a small experiment. Do people think it is nice? Do more! Do people think it sucks? Do less!

2 thoughts on “How to Introduce Elm to a React Codebase

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.