Setting up Elm with Phoenix

Updated: 05/18/2016

Current Versions

Elixir: v1.2.5

Phoenix: v1.1.4

Elm: v0.17.0

Elm-Brunch: v0.4.4

NPM: >3.x

Node: >5.x

Brunch: >2.1.x

Step 1: Creating our application

We’ll start by creating our Phoenix and Elm application the same as we’d create any other Phoenix application. If you need instructions on how to install Phoenix, you can consult the Phoenix Framework site at http://www.phoenixframework.org/docs/installation. We’ll call our app “elm_base”, but you can call it whatever you’d like. Make sure you answer “Y” to fetching and installing dependencies; we’ll need Brunch to be able to do what we need. Beyond that, follow the install instructions that Phoenix feeds back to you.

$> mix phoenix.new elm_base
Answer 'y' to fetch and install dependencies
$> cd elm_base
$> mix ecto.create
$> iex -S mix phoenix.server

Step 2: Setting up Brunch

Now that we have our base Phoenix/Elixir application, we can start working on our front end setup. Run the following to install elm-brunch:

npm install --save-dev elm-brunch

Next, open up brunch-config.js and add the following:

  1. To the “paths/watched” section, add an entry for “web/elm”
  2. To the “plugins” section, add a new block for elmBrunch:
(root)/brunch-config.js

We’re going to start with a simple application called “App.elm”. Make a web/elm directory, and then we’ll add an App.elm file to that with the touch command.

$> mkdir web/elm && touch web/elm/App.elm

We’re going to use the elm-lang/html package for this, so we’ll also install those core libraries.

$> cd web/elm
$> elm package install elm-lang/html
To install elm-lang/html I would like to add the following
dependency to elm-package.json:
"elm-lang/html": "1.0.0 <= v < 2.0.0"
May I add that to elm-package.json for you? (y/n) y
Some new packages are needed. Here is the upgrade plan.
Install:
elm-lang/core 4.0.0
elm-lang/html 1.0.0
elm-lang/virtual-dom 1.0.0
Do you approve of this plan? (y/n) y
Downloading elm-lang/core
Downloading elm-lang/html
Downloading elm-lang/virtual-dom
Packages configured successfully!

Let’s make one quick edit to our Elm application under web/elm/App.elm:

(root)/web/elm/App.elm

I’ll talk about these changes in much greater detail later. Right now we just want to get everything working. Next, I want to embed my Elm application into my Phoenix application so I can see changes as I’m going along. So, we need to modify our Phoenix templates to support our Elm Application. Open up web/templates/layout/app.html.eex and change it to the following:

(root)/web/templates/layout/app.html.eex

And finally replace the contents of web/templates/page/index.html.eex with something simple:

<div id="elm-container"></div>

And the final thing we need to do to get our app up and running. Open up web/static/js/app.js and add the following to the bottom:

// Set up our Elm App
const elmDiv = document.querySelector(‘#elm-container’);
const elmApp = Elm.App.embed(elmDiv);

If we open up our server in the browser now, we should see a simple “Hello World” message appearing somewhere at the top!

Just to verify this isn’t a fluke, let’s modify App.elm one more time, and change our “Hello World!” to “Hello from Elm!” So, we’ll change our main function in App.elm to the following:

main =
text "Hello from Elm!"

And we should see auto-reload kick in and give us:

Step 3: Building more with Elm!

This is a great start and provides us with an excellent foundation to start building crazy fast and crazy functional web apps in Phoenix and Elm! Call this the PEEP stack: Phoenix, Elixir, Elm, and Postgresql!

In the next part of this tutorial series we’ll take a step back from Phoenix and focus a bit more on Elm; understanding what it is, what it does, and learning how to have it interact with some of the more complicated parts of our application (such as sockets!)