Setting up a dev environment in Elm using Atom

It’s as easy as 1,2,… uhh.. 10 #

Our goal is to put together an Elm environment that includes custom HTML/SCSS and is suitable for a professional workflow for web applications.

The approach outlined here puts an emphasis on simplicity and minimal dependencies.

View the source code #

Features of this environment #

Current limitations #

This approach does not yet support use of the elm debugger. If that is unsuitable for you then I encourage you to print this post out and throw it in the trash.

OK, Let’s do this thing. #

1. Install Atom IDE #

Get the Atom installer here. #

I chose Atom over Sublime Text (which is admittedly faster and more stable), Light Table, Microsoft VS Code because it currently has the best Elm language support and is easily extensible.

Maybe I’m backing the wrong horse here but so far Atom is working well for me.

2. Install these Atom packages: #

These can also be installed from within Atom via Settings > Install

3. Install Elm on your computer #

Get the Elm installer here. #


4. Create your application directory structure and core files #

Type the following into your terminal (using Mac OSX - Windows is very similar. We’re just creating files and folders here)

mkdir MyApp
cd MyApp
mkdir src gen css
touch index.html src/Main.elm css/style.css save-commands.json
elm package install
elm package install evancz/elm-html

5. Configure save-commands to build your Elm files whenever you save them. #

The elm make command is the officially supported build tool, so we can just automate that within our IDE instead of using a task runner like Grunt, Gulp, etc.

This part is a little tricky, as at the time of writing there are a couple bugs in this package that throw an error (details below). But it’s ok, we can get through this.

Open up the save-commands.json and enter the following in there.

save-commands.json #
    "timeout": 5000,
    "commands" : [
        "src/**/*.elm : elm make src/Main.elm --output=gen/main.js"

Taking a look at that command in detail… the glob on the left of the colon tells save-commands when you want this command to run. Specifying src/**/*.elm means that it will be run only when we save a file within the src directory, or any of its subdirectories, as long as the file extension is .elm

The command itself is simply the manual elm make command you would use if you weren’t using elm-reactor, targeting only src/Main.elm and outputting it to gen/main.js. The reason we don’t want target all .elm files in the src subdirectory to build is because elm-make is designed to find and compile the necessary dependencies based on the import statements in your code.

Important note: you may get errors on save due to a couple bugs in save-commands. We’re gonna hack this ourselves today, but I expect these will be fixed in the future. Hopefully this will not be necessary in your case.

Commence the Hackery #
  1. In Atom, Go to Settings and click the Open Config Folder button
  2. Find save-commands code under packages > save-commands
  3. Line 107 replace .find('.save-result') with .getElementsByClassName('save-result')[0] (as per this as-yet-unreleased PR)
  4. Save and test
  5. If you get an error about div.prop not being a function, change Lines 114 and 124 from div.scrollTop div.prop('.scrollHeight') to just div.scrollTop
  6. Be a good citizen and submit a pull request for your well-considered, careful modifications

tl;dr this will compile the Main.elm file (and all imported elm modules) to main.js and it will compile whenever you save any .elm file within src, or any of it’s subdirectories.

6. Set up your styles #

This is going to look amazing.

style.scss #
html {
    font-family: "Comic Sans MS", cursive;
    color: magenta;

When you save this file, sass-autocompile will produce a minified css file. Check out the docs to configure this as you like.

7. Set up Main.elm #

This will be your app’s entry point.

src/Main.elm #
module Main where

import Html exposing (text)

main =
    text "wow"

When you save this file save-commands will run elm-make on it, compiling all your Elm code into into gen/main.js.

8. Set up your html #

index.html #
<!DOCTYPE html>
        <meta charset="utf-8">
        <title>My App</title>
        <link rel="stylesheet" href="css/style.min.css">
        <script src="gen/main.js"></script>

Your app structure should now look like this:

├─ css
│    ├─ style.min.css
│    └─ style.scss
├─ elm-stuff
│    └─ ...
├─ gen
│    └─ main.js
├─ src
│    └─ Main.elm
├─ elm-package.json
├─ index.html
└─ save-commands.json

9. Start your local webserver #

Type this in the terminal from your app’s root directory.

elm reactor

10. Gaze upon the glory that is your new application #

Point your browser to localhost:8000/index.html

To verify that your Elm code is compiling on save, edit your Main.elm file and hit save.

src/Main.elm #
module Main where

import Html exposing (text)

main =
    text "much wow...?"

Refresh your browser (auto-refresh/hot-swap would be nice here instead…) and you should see your changes.

Also notice that since save-commands outputs the results of elm-make in a Elm compiler in an Atom pane you won’t need to keep switching to your terminal or browser to see compiler errors!

Next: organising Elm components #


Now read this

Organising Elm components

Quick follow up to my previous post, this assumes that you have set up your app and dev environment in the way I described. 1. Add a Component directory # mkdir src/Component 2. Create a component # touch src/Component/Hello.elm 3. Edit... Continue →