Open-Source Wikis

/

Bun

/

Apps

/

Bake (dev server)

oven-sh/bun

Bake (dev server)

Active contributors: Dylan Conway, Jarred Sumner

"Bake" is the internal name for Bun's full-stack dev server and SSR runtime. It powers bun ./entry.html (with Bun.serve HTML imports), the experimental bun dev, and the React server-component pipeline. Source lives in src/bake/.

Purpose

  • A long-running HTTP server that hot-reloads modules in the browser without a full page refresh.
  • Server-side rendering for React (and other frameworks via FrameworkRouter.zig).
  • Production builds that emit pre-rendered HTML alongside JS chunks.
  • File-system routing — pages are mapped from a pages/ or app/ directory.

Directory layout

src/bake/
├── DevServer.zig                 # ~195 KB — the long-running server
├── DevServer/                    # subroutines: ImportGraph, Watcher integration, sourcemap, ...
├── DevServerSourceProvider.{cpp,h}  # JSC source provider for HMR-aware modules
├── BakeGlobalObject.{cpp,h}      # Bake's JSC subglobal (per-request realm)
├── BakeSourceProvider.{cpp,h}
├── BakeProduction.{cpp,h}
├── BakeAdditionsToGlobalObject.{cpp,h}
├── DevServer.bind.ts             # bindgen file
├── FrameworkRouter.zig           # ~57 KB — file-system routing
├── production.zig                # production build pipeline
├── client/                       # browser-side runtime (TypeScript)
│   ├── hmr-runtime-client.ts
│   ├── hmr-runtime-server.ts
│   ├── hmr-runtime-error.ts
│   ├── hmr-module.ts             # the module shim
│   ├── debug.ts
│   ├── enums.ts
│   └── shared.ts
├── server/
├── bun-framework-react/          # built-in React adapter
├── incremental_visualizer.html   # internal diagnostic UI
├── memory_visualizer.html        # internal diagnostic UI
├── bake.d.ts                     # public types
└── bake.private.d.ts

Key abstractions

Type File Purpose
DevServer src/bake/DevServer.zig The live server. Owns the bundler, the import graph, the watcher subscription, the HMR socket, the framework router.
FrameworkRouter src/bake/FrameworkRouter.zig Maps a request URL → a route + page module + layout chain + server components.
BakeGlobalObject src/bake/BakeGlobalObject.cpp A JSC global that adds Bake-specific intrinsics ($$require$$, server-component tracking) to a per-request realm.
HMRModule (client) src/bake/client/hmr-module.ts Browser-side module shim. Wraps each module so updates can replace its body without losing state.
HMRRuntime (client) src/bake/client/hmr-runtime-client.ts The WebSocket client that receives module updates from the server.

Request flow

sequenceDiagram
    participant Browser
    participant DevServer as DevServer.zig
    participant Router as FrameworkRouter.zig
    participant Bundler as bundle_v2.zig
    participant SSR as ReactServer (in JSC)

    Browser->>DevServer: GET /products/42
    DevServer->>Router: match URL
    Router-->>DevServer: layouts + page module + params
    DevServer->>Bundler: ensure server bundle is fresh
    Bundler-->>DevServer: ready
    DevServer->>SSR: render page tree (in BakeGlobalObject realm)
    SSR-->>DevServer: HTML stream
    DevServer-->>Browser: HTML + chunked JS imports
    Browser->>DevServer: GET /_bun/hmr (WebSocket)
    DevServer-->>Browser: keep open
    Note over Browser,DevServer: file change → DevServer pushes module patch over WebSocket

Hot module replacement

Each browser-side module is wrapped by hmr-module.ts into an HMRModule with:

  • A unique numeric ID assigned at bundle time.
  • An accept() callback for HMR boundaries.
  • Bookkeeping for parents and children to invalidate up the tree.

When a file changes:

  1. Watcher.zig notifies DevServer.zig.
  2. The dev server re-runs the parser on the changed file (other modules stay cached).
  3. The dev server computes a delta — replaced module bodies + import edges that changed.
  4. The delta is pushed to the browser over a WebSocket as { type: "patch", modules: [...] }.
  5. hmr-runtime-client.ts evaluates the new module bodies, walks accept() boundaries, and re-renders.

The error overlay (hmr-runtime-error.ts) is injected into the page from DevServer.zig's HTML response and displays parse errors and runtime errors with sourcemapped stack frames.

Server components

React 19+ server components flow through src/bundler/ServerComponentParseTask.zig. The bundler produces two graphs:

  • A server graph that includes every imported module, runs in the dev server's JSC realm, and emits the React server-component "flight" payload.
  • A client graph that only includes the modules a 'use client' boundary references, ships to the browser, and hydrates the flight payload.

Bake stitches these together at request time. The runtime adapter is src/bake/bun-framework-react/.

Production builds

src/bake/production.zig runs the same pipeline without a dev server. It walks every route, renders to HTML, writes static assets, and produces an optimised JS bundle suitable for serving from a CDN. Routes are determined by the same FrameworkRouter used in dev — the only difference is the SSR step doesn't open a socket.

Framework router

FrameworkRouter.zig accepts a router config (e.g. "Next.js app router", "remix", or a custom one) and walks a directory tree to build a trie of patterns. At runtime, an incoming request is matched against the trie; the result is the layout chain (layout.tsx files from root to leaf), the page module, and any dynamic params ([id].tsxid).

Diagnostic visualisers

  • src/bake/incremental_visualizer.html — interactive view of which modules were affected by recent changes.
  • src/bake/memory_visualizer.html — heap snapshot viewer.

These ship inside the dev server and are accessible at internal /_bun/... URLs in dev mode.

Integration points

  • Bundler — Reuses src/bundler/bundle_v2.zig with hot-mode flags.
  • Watchersrc/Watcher.zig provides change events.
  • HTTP server — Bake runs on top of Bun.serve (src/bun.js/api/server.zig).
  • JSC — A dedicated BakeGlobalObject per server realm. See C++ bindings.

Entry points for modification

  • To add a framework adapter, look at src/bake/bun-framework-react/ as the reference implementation. The adapter exports a default config consumed by FrameworkRouter.zig.
  • To change the HMR protocol, edit both ends together: src/bake/DevServer.zig (server) and src/bake/client/hmr-runtime-client.ts (browser).
  • To change error-overlay rendering, edit src/bake/client/hmr-runtime-error.ts.

Key source files

File Purpose
src/bake/DevServer.zig The dev server.
src/bake/FrameworkRouter.zig File-system routing.
src/bake/client/hmr-module.ts Browser HMR module shim.
src/bake/production.zig Production builds.
src/bake/bun-framework-react/ Built-in React adapter.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Bake (dev server) – Bun wiki | Factory