Volt v0.1 · TypeScript APIs on Bun · Get started
Docs/Core Concepts/Application & Server

Application & Server

Configure the native server, request limits, and shutdown.

Server options

OptionMeaning
portListening port; defaults to 3000
hostnameNetwork interface; defaults to 0.0.0.0
developmentInclude development error details; keep false for public services
maxRequestBodySizeMaximum body size in bytes, forwarded to Bun's server
tlsObject containing certificate and key strings
nativeRoutesBun native static GET dispatch: enabled by default on ARM64; opt-in with true elsewhere; false forces JS dispatch

Complete example

index.ts
import { Volt } from 'voltts';

const app = new Volt({
  port: Number(process.env.PORT ?? 3000),
  hostname: '0.0.0.0',
  development: false,
  maxRequestBodySize: 1024 * 1024,
});
app.get('/health', () => ({ ok: true }));

if (globalThis._importMeta_.main) {
  app.listen();
  process.once('SIGTERM', async () => {
    await app.stop();
    process.exit(0);
  });
}
export default app;

Run and stop

Run bun run index.ts, then request /health. listen() uses the configured port; listen(4000) overrides it. The optional listen callback receives Bun's server instance. await app.stop() stops the native server, runs plugin cleanup, and then the stop callback.

In-memory handling

Use await app.handle(new Request('http://localhost/health')) to dispatch without opening a socket. Register all routes and plugins before calling handle or listen. See Testing and Lifecycle Hooks.

Native static GET routing

On Bun, eligible plain ASCII static GET paths can use Bun's native route table. Native routing defaults to enabled on ARM64 and disabled on other architectures. Set nativeRoutes explicitly to compare both modes:

typescript
import { Volt } from 'voltts';

const app = new Volt({ nativeRoutes: true }); // false selects the JavaScript dispatcher
app.get('/health', () => ({ ok: true, time: Date.now() }));
app.listen(3000);

The handler still runs on every request; responses are not cached. Middleware, validation and error handling remain active. Dynamic and wildcard paths, non-eligible paths, and methods other than GET use Volt's dispatcher. app.handle() and the Node adapter also use the ordinary dispatcher. Measure on your own runtime and workload. See Benchmarks.