In elm your code will automatically be recompiled if

  1. you are using elm-reactor
  2. if you are visiting your main elm file

For example start elm-reactor you'll see

Elm Reactor 0.3.2 (Elm Platform 0.15.1)
Listening on http://0.0.0.0:8000/

Now browse to http://0.0.0.0:8000/Main.elm

Custom html

If you want to use custom html you can define all of this in elm. However this is not a practical solution if you already have html/css/js and you want to reuse parts of that (especially when using ports).

Elm allows you to start the elm app either fullscreen (append to body) or as part of an another element (embed) using your own html file.

Below will show you an example that uses the fullscreen mode with debug functionality.

<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <script src="elm.js"></script>
    <script src="/_reactor/debug.js"></script>
    <script>
var app = Elm.fullscreenDebug('Main', Elm.Main);
    </script>
  </body>
</html>

Auto-recompile

The only problem with this approach is that elm-reactor does not recompile your code when you are not visiting Main.elm directly. You will will have to either visit main.elm or type elm-make Main.elm. Perhaps the functionality will be added to elm-reactor in the future, but for now you can use the following approach for ubuntu.

Create the following script and save it as elm-watch.sh in your project directory.

#!/usr/bin/env bash

if [ $# -eq 0 ]; then
  echo "There should be at least one argument. Which will be passed to elm-make."
  echo "The possible arguments are given by elm-make --help below:"
  echo
  elm-make --help
  exit 1
fi

inotifywait -mr --timefmt '%d-%m-%y %H:%M:%S' --format '%T %w %f' \
-e close_write . | while read date time dir file; do

  if [[ $file == *.elm ]]; then
    FILECHANGE=${dir}${file}
    echo "${time} $FILECHANGE"
    elm-make "$@"
  fi
done

Now run

sudo apt-get install inotify-tools
chmod +x elm-watch.sh
./elm-watch.sh Main.elm

The only disadvantage of this method is that you don't see any errors in your browser but in your terminal window. So you still have a 3rd window to keep an eye on.