Search docs

Jump between documentation pages.

Deno

The Deno adapter wraps Deno.serve — the stable, modern entry point that replaced the old Deno.serveHttp. Graceful shutdown uses an AbortController, which is the pattern Deno itself recommends.

When to choose Deno

  • You want a web-standard runtime with TypeScript built in and no transpile step.
  • You deploy to Deno Deploy, or to a container running the official Deno image.
  • You like Deno's permissions model and don't need the full npm ecosystem.

Scaffold

The deno-basic template ships a Deno-native server with a deno.json import map, watch-mode dev, and deno test.

bash
pnpm create daloy@latest my-api --template deno-basic
cd my-api
deno task dev    # deno run --allow-net --allow-env --allow-read --watch

Install

@daloyjs/core is published to npm. Deno can consume it directly via the npm:specifier — this is the same pattern used by the official deno-basic scaffolder template.

jsonc
// deno.json
{
  "imports": {
    "@daloyjs/core":  "npm:@daloyjs/core@^0.35.0",
    "@daloyjs/core/": "npm:@daloyjs/core@^0.35.0/",
    "zod":            "npm:zod@^4.4.3"
  }
}

Minimal server

ts
// src/server.ts
import { serve } from "@daloyjs/core/deno";
import { app } from "./app.ts";

const ac = new AbortController();

serve(app, {
  port: 3000,
  hostname: "0.0.0.0",
  signal: ac.signal,
  onListen: ({ hostname, port }) =>
    console.log(`listening on http://${hostname}:${port}`),
  // HTTPS:
  // cert: Deno.readTextFileSync("./cert.pem"),
  // key:  Deno.readTextFileSync("./key.pem"),
});

Deno.addSignalListener("SIGTERM", () => ac.abort());
Deno.addSignalListener("SIGINT", () => ac.abort());

Run it

bash
deno run --allow-net --allow-env --allow-read src/server.ts

Deploy to Deno Deploy

Deno Deploy reads the entry script directly. Point your project at src/server.ts; the same file you run locally is what runs in production.

bash
# install once
deno install -gArf jsr:@deno/deployctl

# deploy
deployctl deploy --project=my-api src/server.ts

Dockerfile

docker
FROM denoland/deno:distroless
WORKDIR /app
COPY . .
EXPOSE 3000
CMD ["run", "--allow-net", "--allow-env", "--allow-read", "src/server.ts"]

Gotchas

  • Don't use Deno.serveHttp— it's deprecated. The DaloyJS adapter uses Deno.serve exclusively.
  • On Deno Deploy you don't get SIGTERM; the platform manages shutdown. The AbortController wiring above is for self-hosted Deno only.
  • Use --allow-net(and others) explicitly — Deno's default-deny permissions are the point.

See also