<!-- Skal docs — markdown mirror of https://skal.run/docs/tooling.html -->

# Hot reload & the dev loop

Save-to-screen in under a second — without losing your place in the app. How live reload works, what survives it, and the rest of the daily loop.

## Hot reload

`skal dev <target> --hot` watches `src/`. On save, the new bundle is pushed to the running app and re-evaluated **inside the live JS VM** — no process restart, no native rebuild:

```jsx
↻ App.jsx changed — reloaded in 380 ms
  navigation + hot state preserved
```

The outgoing generation tears down cleanly (its Solid roots dispose, the host resets the widget tree by id), then the new bundle mounts in place. What carries across:

-   **Navigation** — `createRouter` stacks restore, so you stay on the screen you were styling.
-   **Marked state** — `createHotState(initial, key?)` is a drop-in `createSignal` that survives reloads (selected tab, form draft, scroll target).
-   **The store** — `createSkalStore` data was never in the bundle to begin with.

A bundle that throws on reload doesn't brick the session — Skal re-mounts the last good bundle and prints the error, so you fix the typo and save again.

Prefer manual control? Run the bundle watcher (`bun run dev`) in a second terminal and reload with `r` in the `flutter run` one. In release builds, all reload machinery is compiled out — zero overhead ships.

## The rest of the loop

| Command | What it does |
| --- | --- |
| `skal dev <target>` | build + launch — add `--hot` for reload-on-save; auto-boots an emulator if none is attached |
| `bun run test` | host widget tests (`flutter test`) — see [Testing](testing.html) |
| `bun run test:e2e` | Maestro flows against the real app — see [Testing](testing.html) |
| `bun run codegen` | regenerate pub.dev widget adapters — see [Wrapping packages](native.html) |
| `skal build <target>` | shippable release artifact with the bytecode cache baked in |

## Benchmarks

The [published numbers](../#performance) come from the kitchen-sink demo: boot timing prints on every launch (`[skal] init=… boot=…`), the JS tab's bench buttons drive prop-write throughput and the 10,000-item feed, and the in-app meter shows per-frame drain cost live. Methodology and budget invariants: [docs/PERFORMANCE.md](https://github.com/skal-multiplatform/skal/blob/main/docs/PERFORMANCE.md). Run it on your own hardware:

```jsx
$ git clone https://github.com/skal-multiplatform/skal && cd skal
$ SKAL_PREBUILT=1 bun run setup   # prebuilt libskal — no toolchain needed
$ bun run dev:android             # kitchen-sink; watch the boot line + perf meter
```

Every number on this site is reproducible that way. If your hardware disagrees with us, open an issue — that's a bug in the claim or a bug in the code, and either way we want it.

[Previous← Wrapping pub.dev packages](native.html) [NextTesting →](testing.html)
