Server Instance
Creating a Server
import { Server } from "@hornjs/fest";
import { NodeRuntimeAdapter } from "@hornjs/fest/node";
const server = new Server({
adapter: new NodeRuntimeAdapter(),
routes: {
"/": () => new Response("hello"),
},
fetch: () => new Response("Not Found", { status: 404 }),
});
await server.ready();
console.log(server.url);
adapter is optional. In the common Bun, Deno, and Node.js cases you can omit
it entirely unless you need to customize native adapter options or force a
specific runtime configuration.
When omitted, Server lazily resolves a built-in adapter for the current
process with dynamic imports such as import("@hornjs/fest/bun"),
import("@hornjs/fest/deno"), and import("@hornjs/fest/node"):
- Bun ->
BunRuntimeAdapter - Deno ->
DenoRuntimeAdapter - Node.js ->
NodeRuntimeAdapter
import { Server } from "@hornjs/fest";
const server = new Server({
routes: {
"/": () => new Response("hello"),
},
fetch: () => new Response("Not Found", { status: 404 }),
});
await server.ready();
If you prefer, use the convenience factory:
import { serve } from "@hornjs/fest";
import { NodeRuntimeAdapter } from "@hornjs/fest/node";
const server = serve({
adapter: new NodeRuntimeAdapter(),
routes: {
"/": () => new Response("hello"),
},
fetch: () => new Response("Not Found", { status: 404 }),
});
Important Properties
server.options
The normalized options used to build the server.
server.url
The public URL reported by the runtime adapter once listening has started.
server.waitUntil
Register background tasks outside the request pipeline.
server.waitUntil?.(
Promise.resolve().then(() => {
console.log("background startup task");
}),
);
Lifecycle Events
Server extends the typed event system from @hornjs/evt. You can subscribe
to lifecycle transitions with standard event listeners.
serve
Emitted after the runtime adapter reports that the server is listening.
close
Emitted after shutdown completes and all waitUntil() tasks have settled.
error
Emitted when asynchronous runtime adapter initialization fails.
import { Server, ServerErrorEvent, ServerServeEvent } from "@hornjs/fest";
server.addEventListener("serve", (event: ServerServeEvent) => {
console.log("ready at", server.url);
});
server.addEventListener("error", (event: ServerErrorEvent) => {
console.error(event.error);
});
Important Methods
server.fetch(request)
Runs a request through middleware, invocation context initialization, route matching, and the fallback fetch handler when needed.
server.serve()
Starts listening if the server has not already been started.
server.ready()
Waits until the adapter reports that the server is ready.
server.close(closeActiveConnections?)
Stops the runtime adapter and waits for registered background work.
await server.close();
await server.close(true);
Passing true asks the runtime adapter to terminate active connections when it
supports that behavior.
server.close() also dispatches the close lifecycle event once teardown is
finished.
Manual Startup
Set manual: true when you want to delay listening:
const server = new Server({
adapter: new NodeRuntimeAdapter(),
manual: true,
routes: {
"/": () => new Response("ok"),
},
fetch: () => new Response("Not Found", { status: 404 }),
});
await server.serve();
await server.ready();
If you prefer event-driven coordination instead of awaiting ready(), listen
for serve and close directly.