[240] Phoenix and Elm

Using `elm-brunch` to wire your Elm application into Phoenix's default build pipeline.

Subscribe now

Phoenix and Elm [05.13.2016]

At the last ElixirConf, there were a ton of great talks about Elm. I've been doing Elm a ton this year and I just helped some people get Brunch compiling their Elm projects for a Phoenix app, so I thought it would be useful to show how to do that.


Project Setup (off-video)

We'll just make a new Phoenix application:

mix phoenix.new phoenix_elm

Project Details

So we have an empty Phoenix application. Let's make a quick Elm application that we'll show on our home page.

mkdir web/static/elm
vim web/static/elm/Main.elm

This isn't an episode about Elm, so I'll just paste the application in and briefly discuss it:

import Graphics.Element exposing (..)
import Keyboard

main : Signal Element
main =
  Signal.map show Keyboard.arrows

This Elm application will just show the current state of the Keyboard arrows on the screen. Nothing fancy.

How do we get it to be built as part of our Phoenix build pipeline? Phoenix uses brunch, and a nice person built elm-brunch for managing Elm applications in brunch. We can pull it in as an npm package:

npm install --save-dev elm-brunch

And now we just need to configure it in our brunch config:

vim brunch-config.js
  // Configure your plugins
  plugins: {
    babel: {
      // Do not use ES6 compiler in vendor code
      ignore: [/web\/static\/vendor/]
    elmBrunch: {
      // Set to path where elm-package.json is located, defaults to project root (optional)
      // if your elm files are not in /app then make sure to configure paths.watched in main brunch config
      elmFolder: 'web/static/elm',
      // Set to the elm file(s) containing your "main" function
      // `elm make` handles all elm dependencies (required)
      // relative to `elmFolder`
      mainModules: ['Main.elm'],
      outputFolder: '../../../priv/static/js/elm'

If we start phoenix now, we can see it compile our Elm application:

mix phoenix.server

OK, so now we just need to wire it into our template:

vim web/templates/page/index.html.eex
<!-- We load the elm file -->
<script src="/js/elm/main.js"></script>
<!-- Add a container for it -->
<div id="root"></div>
<!-- And embed it into its container -->
  Elm.embed(Elm.Main, document.getElementById("root"));


And that's it. Short and sweet, but now you have a nice build pipeline for integrating your Elm and Phoenix applications. If you're interested in Elm, I've got 8 weeks of content on it at http://dailydrip.com, and once the next version of Elm comes out I'll show how to integrate it with Phoenix Channels. See you soon!