Now available on JSR

Web framework for Deno

No magic. No surprises. Just functions.

No Magic

Routes are functions. Middleware is functions that run before routes. Context is an object. Your code is explicit and traceable, not hidden behind decorators, annotations, or conventions that obscure what's happening.

Security by Default

Path traversal protection is automatic. CSRF uses Sec-Fetch-Site headers. Validation supports Zod, Valibot, or ArkType. You shouldn't have to remember to add security.

Honest Trade-offs

We use O(n) linear routing. It's slower than radix trees for thousands of routes. It's faster for serverless cold starts and simpler to debug. We optimize for the common case.

Mage App

HTTP routing and middleware for APIs and web servers. TypeScript types that actually help. Security middleware that's already written.

import { MageApp, MageError } from "@mage/app";
import { csrf } from "@mage/app/csrf";
import { securityHeaders } from "@mage/app/security-headers";
import { validator } from "@mage/app/validate";
import { z } from "zod";

const app = new MageApp();

// Security middleware - already written, just import and use
app.use(...securityHeaders());
app.use(csrf());

const schema = z.object({
  email: z.string().email(),
  name: z.string().min(1),
});

const { validate, valid } = validator({ json: schema });

app.post("/users", validate, (c) => {
  const { json } = valid(c);
  return c.json({ created: true, user: json });
});

app.get("/users/:id", (c) => {
  const user = db.find(c.req.params.id);
  if (!user) throw new MageError("Not found", 404);
  return c.json(user);
});

Deno.serve(app.handler);

Mage Pages

Static site generator for documentation and content sites. Markdown or Preact components. File-based routing. Builds to static files you can deploy anywhere.

// Directory structure becomes URL structure
// pages/index.md       → /
// pages/docs/intro.md  → /docs/intro
// pages/about.tsx      → /about

import { MageApp } from "@mage/app";
import { pages } from "@mage/app/pages";

const app = new MageApp();
const { registerDevServer } = pages();

registerDevServer(app);

Deno.serve(app.handler);

What Mage Isn't

Not a batteries-included framework with opinions on databases or authentication. Not a mature ecosystem with hundreds of plugins. Not trying to be Rails or Django for Deno.

Mage is a solid foundation with good defaults for developers who want to make their own architectural decisions. Mage Pages adds optional frontend support with Preact and Markdown, but it's opt-in. Use what fits your project.