CONCRETE 010: Live Reload While You Edit

Summary:

Every demo under example/ now reloads itself while you work on it. Run a demo, open it in a browser, edit the module or template behind it, save the file – the tab in front of you updates on its own. No manual recompile, no manual refresh. And when a save leaves you with a syntax error instead of working code, the browser tells you so directly, with the real compiler output, instead of just quietly showing you yesterday's page.

What Happens When You Save

Nothing to turn on, nothing to configure. Start any demo the usual way:

rebar3 as example shell
ws_demo:serve().

Open http://localhost:8772 the way you always would, then open example/ws_demo.erl (or example/ws_demo_page.erl, or the .slab template behind whichever demo you're looking at) in your editor. Change some text that shows up on the page – a label, a button's text, a line of copy – and save.

Within about a second, the tab reloads on its own. No manual rebar3 compile, no switching windows to check whether the build finished, no habitual Cmd-R. The page in front of you is already showing your edit.

This works whether you start one demo directly (ws_demo:serve(), template_demo:serve(), and so on) or bring all of them up at once with demo_parent:serve(). Every demo it starts gets the same behaviour.

Editing a Template vs. Editing Erlang Code

There's a small, noticeable difference in how fast the reload feels, depending on what you touched.

Edit a .slab template – priv/templates/scoreboard.slab for the Template/Scoreboard demo, or priv/templates/ws_demo.slab for the WebSocket demo – and the reload is close to instant. Templates are just markup; there's nothing to compile.

Edit a .erl module and there's a brief pause, long enough to notice, before the reload fires. That pause is a real rebar3 as example compile running against your change. Once it finishes successfully, the reload happens the same way. On most machines this lands well under a couple of seconds for a small edit – long enough to see, short enough that it doesn't break your flow.

When a Save Doesn't Compile

Leave a module in a broken state – a missing comma, an unbalanced clause, whatever – and save it anyway, and the browser doesn't just sit there showing the last good page with no explanation. A panel drops down from the top of the tab showing the actual compiler output: the same text you'd see if you'd run the compile yourself in a terminal, telling you which file and which line.

===> Compiling example/ws_demo.erl failed
     ┌─ example/ws_demo.erl:
     │
 150 │  this is not valid erlang(((
     │       ╰── syntax error before: is

Fix the syntax error and save again. The panel clears itself, the recompile succeeds, and the page reloads with your fix in place – the same as any other successful save.

Try It Yourself

The fastest way to feel this out:

  1. rebar3 as example shell
  2. ws_demo:serve().
  3. Open http://localhost:8772 in a browser, side by side with your editor.
  4. Open example/ws_demo.erl, find the paragraph of body text in page_shell/1, change a sentence, save. Watch the tab refresh on its own.
  5. Now break something on purpose – delete a closing parenthesis somewhere in the same file – and save. Watch the error panel appear with the real compiler message.
  6. Put the parenthesis back, save once more, watch the panel disappear and the page come back.

Every other demo behaves the same way – swap in template_demo:serve(), task_board_demo:serve(), or demo_parent:serve() to bring all of them up together, and edit whichever module or template sits behind the one you're looking at.

What Doesn't Reload Yet

A handful of demos – the canvas animation, the gen-server counter, the process-ring visualization, the three.js spirograph, and multiplayer snake – build their compiled JavaScript once, when the demo starts, and write it to a file rather than regenerating it on every page load. Editing the Erlang behind one of these still recompiles correctly, but the JavaScript the browser actually runs won't pick up your change until you stop the demo and start it again. Every other demo – the WebSocket demo, Template/Scoreboard, the task board, and the todo list – regenerates what it sends the browser on every request, so those reload exactly as described above with no extra step.

Resources: