Skip to main content
Bun supports two automatic reloading modes:
  • --watch — hard restarts the process when imported files change.
  • --hot — soft reloads code without restarting the process.
Restarts the entire Bun process when a file changes. All global state is reset. Suitable for scripts, CLI tools, and test suites.

--watch mode

Run a file and restart it automatically whenever any imported file changes:
bun --watch run index.tsx
Run tests and re-run them on every file change:
bun --watch test
In --watch mode, Bun:
  • Tracks all imported files and watches them for changes.
  • Restarts the process with the same CLI arguments and environment variables on change.
  • Automatically restarts if the process crashes.
Bun uses operating system native filesystem APIs (kqueue on macOS, inotify on Linux) rather than polling. This makes watch mode fast even in large projects.

Example: live-reloading an HTTP server

import { serve } from "bun";

console.log("I restarted at:", Date.now());

serve({
  port: 4003,
  fetch(request) {
    return new Response("Sup");
  },
});
bun --watch run server.ts
Every time you save server.ts, the process restarts and re-runs from the top.

--no-clear-screen

In environments where multiple watch processes run simultaneously (e.g., with concurrently), use --no-clear-screen to prevent each reload from clearing the terminal:
bun build --watch --no-clear-screen
This behaves like TypeScript’s --preserveWatchOutput.

--hot mode

Use --hot to enable hot reloading. Unlike --watch, Bun does not restart the process. Instead, it detects file changes, resets the internal module cache, and re-evaluates changed files. All global state stored on globalThis is preserved across reloads.
bun --hot run server.ts
Starting from the entry point, Bun builds a registry of all imported source files (excluding node_modules) and watches them for changes.

Tracking reload count

Because globalThis persists across reloads, you can use it to track state:
declare global {
  var count: number;
}

globalThis.count ??= 0;
console.log(`Reloaded ${globalThis.count} times`);
globalThis.count++;

// Keep the process alive
setInterval(function () {}, 1000000);
Running this with bun --hot run server.ts and saving the file prints an incrementing count:
Reloaded 1 times
Reloaded 2 times
Reloaded 3 times

HTTP servers with --hot

--hot is particularly useful with HTTP servers. When you save the file, Bun re-evaluates the module and the server picks up the new request handler — without closing the port or losing connections.
globalThis.count ??= 0;
globalThis.count++;

Bun.serve({
  fetch(req: Request) {
    return new Response(`Reloaded ${globalThis.count} times`);
  },
  port: 3000,
});
Unlike traditional tools like nodemon, which restart the entire process and tear down the HTTP server, bun --hot reflects code changes in-place. This results in much faster iteration cycles.
--hot is the server-side equivalent of browser hot reloading. For hot reloading in the browser (e.g., React component updates without a page refresh), use a framework like Vite.

Comparison

Feature--watch--hot
Full process restartYesNo
Global state preservedNoYes (globalThis)
Works with bun testYesNo
Works with HTTP serversYes (reconnects)Yes (no downtime)
Crash recoveryYesNo

bun test --watch

Run your test suite in watch mode. On every file change, Bun re-runs the affected tests:
bun --watch test
To run a specific test file in watch mode:
bun --watch test src/utils.test.ts

Build docs developers (and LLMs) love