Hot reload

sluurp serve watches the app's folder. Save a file and every open page changes to match, in place: a counter keeps its count, an open dialog stays open, what you typed stays typed. There is nothing to set up, and no bundler to run.

sluurp serve --public ./app

What is swapped in place

The new version of the module you saved replaces the old one, and the page keeps its state. Each of these is a case in the hot lab, a test app that saves every kind of edit in turn and checks that the page kept its state:

  • Components: a component’s own state, a signal at the top of a module, an open dialog, a list of keyed rows, a child component in another file.
  • Plain modules: a .ts file that components import, two imports deep, or on either side of a circular import.
  • Data and assets: a .json file, import.meta.glob (a file added or deleted too), ?raw and ?url imports, import.meta.env from .env.
  • Styles: a stylesheet, or a CSS module, swapped with no redraw at all.
  • Workers: a TypeScript worker, started again with the new code.
islands/counter.tsx
import { signal } from "sluurp/reactive";

export default function Counter() {
  const count = signal(0);
  // Change this label and save: the count stays where it was.
  return <button onClick={() => count.set(count() + 1)}>Clicked {count} times</button>;
}

What redraws the page

  • A Markdown page, a layout or a route drawn on the server is drawn again and the page updated, with no reload.
  • A module that does something when it loads (a statement at its top level, not only definitions) reloads the page, since running it twice would do it twice.

When something breaks

A save that doesn’t compile, or code that throws, shows in the dev overlay: the error at its line in your source, with a link that opens the file in your editor. Problems that aren’t fatal (a refused request, a console.error) are counted in a corner of the page instead of interrupting it. Fix the file and save; the overlay clears itself.

In production

Hot reload is for development. Serve with --no-hot-reload, or publish the app as a bundle, and nothing is watched and no reload script is sent.

The hot lab is e2e/hot-lab, with one card for each of these cases. Its browser test edits each one and checks it swapped in place and kept its state.