interface

Serve.DirectoryRouteOptions

interface DirectoryRouteOptions

Serve a directory tree at a URL prefix.

The route path must end in /*. The part of the request URL after the prefix is percent-decoded once and opened relative to dir. Non-canonical paths (containing ., .., empty segments, %2F, or a %XX sequence encoding a character that may appear literally in a path segment) are rejected with 404 so the served path is always the path the router matched. On Linux the open uses openat2(RESOLVE_IN_ROOT), so symlinks that would escape dir are clamped by the kernel. Routing is case-sensitive but filesystems on macOS and Windows are not by default: do not place access-controlled content inside dir and rely on an overlapping route to gate it.

Responses carry Content-Type (from the file extension), Last-Modified, a weak ETag, and support single-range Range requests. A request that resolves to a directory without a trailing / is redirected (301) to the trailing-slash URL; with the trailing slash, index.html from that directory is served. Missing files return 404.

Bun.serve({
  routes: {
    "/static/*": { dir: "./public" },
  },
});
  • dir: string

    Path to the directory to serve.

  • statCache?: boolean

    Cache formatted Last-Modified strings per path so repeated requests for an unchanged file skip the date formatter. Uses ~20 KB per route.