It took me some time to figure out how this combination works. Finally, it is rather easy.

Starting from …

  • mix new myapp --umbrella
  • cd apps
  • mix myweb

… you should have a running Phoenix application now.

Add Elm

  • cd apps/myweb/lib/mywebweb/assets
  • npm install elm --save-dev
  • elm package install -y elm-lang/html

Add Your Elm App

  • mkdir assets/elm
  • mkdir assets/elm/src
  • touch assets/elm/src/Main.elm

Edit Main.elm

module Main exposing (..)   
import Html exposing (h1, text, p, div)
import Html.Attributes exposing (style)
elmStyle =
    [ ("backgroundColor", "darkred")
    , ("height", "auto")
    , ("width", "100%")
    , ("color", "white")
    , ("padding", "1em" )

main =
  div [ elmStyle ]
  [ h1 [] [ text "Hello, Elm!"]
  , p [] [text "This is Elm in an elixir/phoenix umbrella app"]

Modify brunch-config.js To

exports.config = {
  files: {
    javascripts: { joinTo: "js/app.js" },
    stylesheets: { joinTo: "css/app.css" },
    templates: { joinTo: "js/app.js" }
  conventions: { assets: /^(static)/ },
  paths: {
    watched: ["static", "css", "js", "vendor", "elm"],
    public: "../priv/static"
  plugins: {
      babel: { ignore: [/vendor/] },
      elmBrunch: {
      mainModules: ["elm/src/Main.elm" ],
      makeParameters: ["--debug"],
      outputFile: "elm.js",
      outputFolder: "../assets/js"
  modules: {
    autoRequire: { "js/app.js": ["js/app"] }
  npm: { enabled: true }

Add A “div” For The Elm Application

in any of your phoenix-template-files

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

Add The Following Code To The End Of assets/app.js

// Elm
import Elm from "./elm";
const elmContainer = document.querySelector("#elm-container");
if (elmContainer) Elm.Main.embed(elmContainer);


If you’re using Git, you may add the following lines to your .gitignore file



Your application should now show


wherever you put the div-tag mentioned above.

When you edit your Main.elm application, brunch will compile all js-code and you should see your changes in the browser within the blink of an eye (no reload necessary).