Skip to main content
meow:http exposes a single function, serve(), that starts a Web-standard HTTP/1.1 server. Your handler receives a standard Request and returns a standard Response (or a promise of one) — the same objects you use with fetch.
import { serve } from "meow:http";

serve((req: Request) => {
  return new Response("Hello from meow!\n");
}, { port: 3000 });

serve()

Accepts either a handler-first or an options-only (Deno-style) form:
serve(handler, { port: 3000 });          // classic
serve({ port: 3000, fetch: handler });    // Deno-style
function serve(
  handlerOrOptions: Handler | ServeOptions,
  maybeOptions?: ServeOptions,
): Server;

type Handler = (request: Request) => Response | Promise<Response>;
The listener binds synchronously, so server.addr carries the resolved address the moment serve() returns.

ServeOptions

port
number
default:"8000"
TCP port to bind. Pass 0 to let the OS assign a free port (read it back from server.addr.port).
hostname
string
default:"\"0.0.0.0\""
Interface to bind.
signal
AbortSignal
Abort to stop accepting connections and drain in-flight requests.
onListen
(addr: NetAddr) => void
Called once the listener is bound, with the resolved { hostname, port }.
fetch
Handler
The per-request handler, when using the options-only form.

Server

interface Server {
  readonly addr: NetAddr;          // { hostname, port } — resolved
  shutdown(): Promise<void>;       // stop accepting, drain, release. Idempotent.
  readonly finished: Promise<void>; // resolves when the accept loop fully stops
}

interface NetAddr {
  readonly hostname: string;
  readonly port: number;
}

Examples

import { serve } from "meow:http";

const user = new URLPattern({ pathname: "/users/:id" });

serve((req) => {
  const match = user.exec(req.url);
  if (match) {
    return Response.json({ id: match.pathname.groups.id });
  }
  return new Response("Not found", { status: 404 });
}, { port: 3000 });

Error handling

  • A handler that throws, or returns something other than a Response, yields a 500 and logs the failure — one bad request never takes down the server.
  • If the listener can’t bind — for example, the port is already in use — the error surfaces through server.finished (it rejects) rather than throwing out of serve().

meow:ui

On-brand status output for your programs and scripts.