Server
Boot the HTTP server that hosts the user's Patties app. The framework wraps Bun.serve() and uses its native routes: map (introduced in Bun 1.2) as the dispat…
Purpose
Boot the HTTP server that hosts the user's Patties app. The framework wraps Bun.serve() and uses its native routes: map (introduced in Bun 1.2) as the dispatcher. There is no third-party HTTP framework — request matching, param parsing, and static-route handling all run in Bun's C++ path.
Public surface
export function createServer(options: ServerOptions): { fetch: (req: Request) => Response | Promise<Response>, port: number }
export function startServer(options: ServerOptions): Bun.Server
ServerOptions:
port?: number— default3000.hostname?: string— default0.0.0.0.unix?: string— optional Unix socket path. When set,port/hostnameare ignored. Useful for self-hosted deploys behind nginx / Caddy.reusePort?: boolean— passed through toBun.serve. EnablesSO_REUSEPORTso multiple processes can bind the same port for horizontal scaling (bunadapter, multi-core hosts).routes: BunRoutes— the compiled route map from 02-router. Each key is a Bun pattern (e.g./hotels/:city); each value is aResponse(precomputed) or a method-keyed object whose handlers are already wrapped by the user middleware composer.fallback: (req: Request) => Response | Promise<Response>— thefetch:handler. Wraps a 404 handler in the user middleware so unmatched paths still flow through middleware.dev?: boolean— when true, mounts the HMR WebSocket from 05-dev-hmr.staticRoutes?: Record<string, Response>— prebuiltResponseobjects for/_patties/client/*chunks and (in thebunadapter)/app/public/*files. Bun.serve matches these before JS runs, so they never enter a handler.
Behavior
- Validate
options(routesrequired;port/hostnameandunixare mutually exclusive). - Construct
Bun.serve({ port, hostname, unix, reusePort, routes, fetch: fallback, websocket?, static: staticRoutes }). - If
dev: true, register the HMR upgrade handler on path/__patties_hmrvia thewebsocketoption and a routes entry that callsserver.upgrade(req). - Log the bound URL on startup (or socket path when
unixis set). - Forward unhandled errors to a single error formatter; never let
Bun.servecrash silently.
Why native routes (not a userland router)
Bun.serve({ routes }) matches paths in C++ before any JS runs, populates req.params natively, and short-circuits static responses without a JS round-trip. For the bun target the gain is real; more importantly, it removes a whole layer of abstraction (Hono app.use, c.req.param, etc.) and lets the framework expose plain Request/Response. The edge adapter (12) compiles the same route table into a small JS matcher for vendors that don't accept routes: natively — same handlers, same ctx, different entrypoint shape.
Dependencies
Bun.serveonly — no Nodehttp,https, ornet. No HTTP framework.
Non-goals
- TLS termination (delegate to the edge / reverse proxy).
Bun.servesupportstls:; users opting into a non-proxied deploy may configure it throughpatties.config.tsserver.tls. - Process supervision, clustering, graceful shutdown choreography beyond
server.stop(). Bun.serve({ routes })alternatives. The framework does not maintain a hand-written matcher on the Bun target.
Acceptance criteria
createServer({ routes, fallback })returns an object whosefetchresolves end-to-end.- A GET to
/on a one-route fixture returns200and HTML. - A POST to
/api/users/:idresolvesreq.params.idvia Bun's native parser; the handler receives the frameworkctxpopulated by the middleware composer. - Importing this module never pulls in
node:httporhono(verified by a build-time check).