Rails 5.1 makes it easier to sprinkle bits of Elm into your Rails app, or even to go all in with Elm! Here’s a quick rundown of how to start using Elm with Rails:

  1. First, create a new Rails 5.1 app using the --webpack option:

    rails new elm_on_rails --webpack
    
  2. Next, change into the generated application directory and install everything needed for Elm with the help of Webpacker:

    rails webpacker:install:elm
    

    This runs elm package install which downloads and installs the Elm packages elm-lang/core, elm-lang/html, and elm-lang/virtual-dom.

  3. Now pop open an editor in the application directory and navigate to the app/javascript/packs directory. You’ll find a generated Main.elm file that displays “Hello Elm!” text. You’ll also find a companion hello_elm.js file that embeds the output of Main.elm in the HTML document:

    import Elm from './Main'
    
    document.addEventListener('DOMContentLoaded', () => {
      const target = document.createElement('div')
    
      document.body.appendChild(target)
      Elm.Main.embed(target)
    })
    
  4. You need a page to display the Elm output. Any page will do since hello_elm.js embeds the output in the current document. I ended up making an app/views/application/index.html.erb file. In that file, use the javascript_pack_tag helper to import the hello_elm.js file:

    <%= javascript_pack_tag "hello_elm" %>
    

    Then I added a default route in config/routes.rb to that page:

    get '/', to: 'application#index'
    
  5. Game time! Fire up the Rails server:

    rails s
    

    In development, you also need to run a Webpack Dev Server in a separate terminal so that Elm files are automatically compiled as you make changes:

    ./bin/webpack-dev-server
    
  6. Browse over to http://localhost:3000 and you should see the “Hello Elm!” greeting.

Countdown Timer

To kick things up a notch and see another example, here’s how to integrate the countdown timer we build in our free Integrating Elm course:

  1. Paste CountdownTimer.elm and countdown_timer.js into the app/javascript/packs directory.

    Notice that the countdown_timer.js file embeds the timer in a DOM element with the id of countdown-timer:

    import Elm from './CountdownTimer'
    
    document.addEventListener('DOMContentLoaded', () => {
      const target = document.getElementById('countdown-timer')
    
      Elm.CountdownTimer.embed(target, {
        deadline: "May 30 2017 14:05:00"
      });
    })
    
  2. Import countdown_timer.js in your app/views/application/index.html.erb file and add an element with the id of countdown-timer:

    <%= javascript_pack_tag "countdown_timer" %>
    
    <div id="countdown-timer"></div>    
    
  3. The countdown timer relies on a touch of style, so paste timer.css into the app/assets/stylesheets/timer.css file.

  4. Reload and the timer should start ticking down!

Bonus: Use Foreman

In development, you can sidestep having to run the Webpack Dev Server separately by using the foreman gem.

  1. Add the gem to your Gemfile:

    gem 'foreman'
    

    And install it:

    bundle install
    
  2. Then create a Procfile in the top-level application directory with the following two lines:

    web: ./bin/rails server
    webpack: ./bin/webpack-dev-server
    
  3. Now you can start the Rails server and the Webpack Dev Server in one fell swoop using:

    foreman start
    

It’s never been easier to integrate Elm into a Rails app, and I suspect it will only get smoother from here!

Build a complete Elm web app from start to finish!

Quickly get up to speed with Elm and functional programming as you build a reactive web app step-by-step in our 3.5-hour Building Web Apps With Elm video course. You go from a new project to talking to a JSON API, and everything in between!