---
title: Hot reload
description: Save a file and the page changes in place, keeping what you were doing.
section: Frontend
order: 5
---

# Hot reload

<p class="lead"><code>sluurp serve</code> 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.</p>

```sh title="Terminal"
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.

```tsx title="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`](https://github.com/SluurpHQ/sluurp/tree/master/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.
