Hot Reload

Hot Reloading is a feature of Ema’s Live Server wherein any changes to your Haskell source or data files (such as Markdown files or HTML templates) propagate instantly to the web browser without requiring any manual intervention like a full browser refresh. In practice, this is a such a delightful feature to work with. Imagine changing CSS style of an element, and see it reflect on your site in a split second.

How Ema implements hot reload


The Ema dev server uses websockets to keep a bi-directional connection open between the web browser and the Live Server. When you click on a link or when something changes in the backend, they are communicated via this connection. In a statically generated site, however, no such activity happens - and a link click behaves like a normal link, in that the browser makes a full HTTP request to the linked page.

DOM patching

When switching to a new route or when receiving the new HTML, Ema uses morphdom to patch the existing DOM tree rather than replace it in its entirety. This, in addition to use of websockets, makes it possible to support instant hot reload with nary a delay.

Haskell reload

Finally, hot reload on code changes are supported via ghcid. The template repo's `bin/run` script uses ghcid underneath. Any HTML DSL (like blaze-html) or CSS DSL automatically gets supported for hot-reload. If you choose to use a file-based HTML template language, you can enable hot-reload on template change using the unionmount library.

Note that if your application makes use of threads, it is important to setup cleanup handlers so that ghcid doesn’t leave ghost processes behind. Helpers like race_ will do this automatically (incidentally it is used by runEma for running the user IO action).

Data reload

For anything outside of the Haskell code, your code becomes responsible for monitoring and updating the Model type Dynamic. The unionmount library already provides utilities to facilitate this for monitoring changes to files and directories.

Handling errors

If your code throws a Haskell exception, they will be gracefully handled and displayed in the browser, allowing you to recover without breaking hot-reload flow.

Links to this page
  • Live Server

    The “run” command of CLI runs the live-server, as opposed to the “gen” command which generates the static site one off. The live-server is a simple HTTP server that serves the Ema site “on the fly” (without doing O(n) static-site generation). Furthermore, changes to your Model type (via Dynamic) will automatically Hot Reload the browser clients to display the new HTML as rendered using the new model value.

  • Getting Started

    Step 3 starts the Ema Live Server displaying a simple website. Try modifying the HTML DSL in the Haskell source ./src/Main.hs, and observe how the browser-view updates instantly.

  • Dynamic Model

    In Add a Model, we modified our mood tracker to display the moods from a CSV file. Here, we improve it so that any user modifications to the data/moods.csv file will hot reload the Live Server view of our app in the same manner as Emanote does.

  • Dynamic

    The use of a time-varying Dynamic is what enables Hot Reload. See here for an example of making a model time-varying. Checkout unionmount to produce a Dynamic of a model that updates based on the filesystem tree.

    The EmaSite’s siteInput method returns a Dynamic of Model type, which represents all the data required to render a site. If you do not want Hot Reload, you may return a pure value.

    Dynamic’s are essential to support Hot Reload.

  • Asset

    Live Server specifically looks at the Asset Generated . Html asset and Hot Reloads the browser on its change.

  • Add a Model

    This is great so far—we can track how we feel in moods.csv and get an app-like “view” of it. But, we don’t have Hot Reload. Changing data/moods.csv ought to update our site. The final step of our tutorial series will explain this.