Walkthrough: Introducing Elm to a JS Web App
When we introduced Elm to our production front-end at [NoRedInk](https://www.noredink.com/jobs), we knew what to expect: the productivity benefits of an incredibly well-built language, and the intrinsic risk of integrating a cutting-edge technology for the first time. Knowing these risks, we came up with a minimally invasive way to introduce Elm to our stack, which let us get a sense of its benefits without having to make a serious commitment. Since several people have asked me about this, I’d like to share how we did it! This walkthrough assumes only a beginner level of Elm familiarity. I won’t be spending much time on syntax (though I will link to the [syntax guide](http://elm-lang.org/docs/syntax) as a reference) or functional programming staples like [map](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/List#map) and [filter](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/List#filter), so I can go into more depth on introducing Elm to an existing JS codebase. Let’s dive in! ## Elm for…business logic? Elm is known for its UI-crafting capabilities (both as [an improvement over React](http://elm-lang.org/blog/blazing-fast-html) as well as for [game programming](https://github.com/BlackBrane/destroid)), but building out an entire UI in a new language was more commitment than we wanted to tackle as a starting point. We didn’t want a drink from the fire hose; we just wanted a little sip. Fortunately, it turns out Elm is also a phenomenal language for writing business logic. Besides making it easy to write clear, expressive code, Elm also makes it easy to write code that’s rock-solid reliable. How reliable? Here are some numbers: * Students answer over 2.5 million questions per day on NoRedInk. Needless to say, edge cases happen. * [3% of our code base](https://twitter.com/rtfeldman/status/628433529538412544) (so far!) is Elm code. Not a ton, but a substantial chunk. * We have yet to see our production Elm code cause a single runtime exception. This is not because we sheltered it; our production Elm code implements some of the most complicated parts of our most mission-critical features. Despite that level of exposure, every runtime browser exception we’ve ever encountered—in the history of the company—has been fixed by changing CoffeeScript or Ruby code. Never by changing Elm code. This is also not because we have some particularly unusual code base; rather, it’s because Elm’s compiler is astonishingly helpful. Let’s get a taste for that by introducing Elm to an existing JavaScript code base! **Adding a hint of Elm to a JS TodoMVC app** We’ve been using [React](http://reactjs.com/) and [Flux](https://facebook.github.io/flux/docs/overview.html) at NoRedInk since they came out in 2014. Flux stores are a convenient place to introduce Elm to your code base, because they’re all about business logic and are not concerned with UI rendering. Porting a single Flux store to Elm proved a great starting point for us; it was enough to start seeing real benefits, but not such a big commitment that we couldn’t have changed our minds and turned back if we’d wanted to. Let’s walk through doing the same thing: porting a store from the [Flux TodoMVC](https://github.com/facebook/flux/blob/master/examples/flux-todomvc/js/stores/TodoStore.js) example to Elm. First, grab Facebook’s [Flux](https://github.com/rtfeldman/flux) repo. (I’m linking to a fork of their repo, in case theirs has changed since I wrote this.) and `cd` into its directory. At this point you should be able to [follow the instructions for building the TodoMVC example](https://github.com/rtfeldman/flux/tree/35b040e213149b9577dc253d9ca1a4ba086f1159/examples/flux-todomvc#running).
git clone git@github.com:rtfeldman/flux.git cd examples/flux-todomvc npm install npm start
Once you have npm start running, you should be able to open the index.html file in your current directory and see a working app.
If you’re not familiar with the Flux architecture (it’s conceptually similar to The Elm Architecture), now might be a good time to read about it. You don’t need a ton of experience with it to follow along, but having a general idea what’s going on should help.
Now you’ll want to grab yourself a copy of Elm. Either use npm install -g elm or visit elm-lang.org/install to get an installer. When you’re finished, run elm make --help in your terminal and make sure it says Elm Platform 0.15.1 at the top!
Integrating Elm at a basic level requires three things:
- A
.elmfile containing our Elm code. - An elm-package.json file specifying our dependencies.
- A JavaScript command to invoke our Elm code.
Let’s create examples/flux-todomvc/TodoStore.elm with the following code:
module TodoStore where
port dispatchCreate : Signal String
Now let’s build it by running this command in the examples/flux-todomvc/ directory:
$ elm make TodoStore.elm --output elm-todomvc.js
The first time you build, you should see this prompt:
Some new packages are needed. Here is the upgrade plan. Install: elm-lang/core 2.1.0 Do you approve of this plan? (y/n)
After you answer y, Elm will install your dependencies. When it’s done, you should see this message:
Successfully generated elm-todomvc.js.
So far, so good!
Your directory should now contain an elm-package.json file and the compiled elm-todomvc.js file generated by elm make, as well as an an elm-stuff/ folder which holds downloaded packages and the like. I always add elm-stuff/ to .gitignore.
Next we need to add our compiled Elm code to the page.
If we’d incorporated gulp-elm into our project’s Gulpfile (see also grunt-elm, elm-webpack-loader, and this Gist for Sprockets integration), then our compiled Elm code would already be included as part of bundle.js. However, we’re avoiding build tool plugins for this example, so we need to tell our index.html file about elm-todomvc.js by adding a new <script> tag above the one that imports "js/bundle.js" like so:
...
<script src="elm-todomvc.js"></script><script src="js/bundle.js"></script>
22 notes
icestarstorm liked this illcures-blog liked this
russmatney liked this
jambambles liked this azspot liked this
manda-cfb liked this
aneaglenamedsmallgovernment-blog liked this vantischen reblogged this from noredinktech
vantischen liked this
ygorgeurts-blog-blog liked this
crookedblazedinosaur-blog liked this doppioslash liked this
gregrv liked this
grafofilia liked this
ripht-blog liked this devthewild liked this
evandrix reblogged this from noredinktech
evandrix liked this
frontrowed liked this
joeinjesus liked this
maxlewin liked this
watnotevenmad liked this
noredinktech posted this