Built and signed on GitHub ActionsBuilt and signed on GitHub Actions
Build web applications with Deno
Mage
A no-nonsense web framework for Deno
Why Mage?
No-frills. Just routing, middleware, and the essentials. No magic, no surprises.
Secure by default. CSRF protection, CORS, CSP, rate limiting, and path traversal prevention built-in.
Simple and explicit. Minimal abstractions. Predictable behavior. Easy to debug.
TypeScript-native. Full type safety without configuration.
Quick Start
deno add jsr:@mage/app
import { MageApp } from "@mage/app"; const app = new MageApp(); app.get("/", (c) => { c.text("Hello, world!"); }); Deno.serve(app.handler);
Run it: deno run --allow-all main.ts
What's Included
Core
- app - Routing, middleware, context management
- linear-router - Simple O(n) router
Middleware
- body-size - Request body size limits
- cache-control - Cache-Control header management
- compression - Gzip response compression
- cors - Cross-Origin Resource Sharing
- csrf - CSRF protection using Fetch Metadata
- csp - Content Security Policy headers
- rate-limit - Sliding window rate limiting
- request-id - Request ID tracking and tracing
- security-headers - HSTS, X-Frame-Options, etc.
- serve-files - Static file serving with cache-busting
- timeout - Request timeout enforcement
- validate - Schema validation (Zod, Valibot, ArkType, etc.)
Utilities
- cookies - Signed cookie utilities
- logs - Console logger with colored output
- status - HTTP status code utilities
Static Site Generator
- pages - Markdown + Preact layouts with file-based routing
Built-in hot reload, asset cache-busting, and static builds. Requires Preact:
deno add jsr:@mage/app npm:preact npm:preact-render-to-string
Add to your deno.json:
{ "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "preact" } }
Import Examples
import { MageApp } from "@mage/app"; import { cors } from "@mage/app/cors"; import { rateLimit } from "@mage/app/rate-limit"; import { pages } from "@mage/app/pages";
Example: REST API
import { MageApp } from "@mage/app"; import { cors } from "@mage/app/cors"; import { rateLimit } from "@mage/app/rate-limit"; import { validator } from "@mage/app/validate"; import { z } from "npm:zod"; const app = new MageApp(); // Security middleware app.use(cors()); app.use(rateLimit({ max: 100, windowMs: 60000 })); // Validated endpoint const createUserSchema = z.object({ name: z.string().min(1), email: z.string().email(), }); const { validate, valid } = validator({ json: createUserSchema }); app.post("/users", validate, async (c) => { const { json } = valid(c); const user = await db.users.create(json); c.json(user, 201); }); app.get("/users/:id", async (c) => { const user = await db.users.find(c.req.params.id); if (!user) return c.notFound(); c.json(user); }); Deno.serve(app.handler);
Example: Static Site
import { MageApp } from "@mage/app"; import { pages } from "@mage/app/pages"; const { registerDevServer } = pages(); const app = new MageApp(); registerDevServer(app, { rootDir: "./docs" }); Deno.serve({ port: 3000 }, app.handler);
Write Markdown with frontmatter, create Preact layouts - get a static site with hot reload in development and optimized builds for production. See pages module for details.
Performance
~50,000 req/sec on Apple M1 Max (simple routes)
Cold start: < 1ms for typical apps (< 100 routes)
Mage is ~15-30% faster than Oak, ~2.5x slower than Hono. Performance won't bottleneck 99.9% of applications.
See benchmarks for detailed comparison.
Documentation
Each module has its own README with detailed usage, examples, and API reference. Start with app for core concepts.
License
MIT
Add Package
deno add jsr:@mage/app
Import symbol
import * as app from "@mage/app";
Import directly with a jsr specifier
import * as app from "jsr:@mage/app";
Add Package
pnpm i jsr:@mage/app
pnpm dlx jsr add @mage/app
Import symbol
import * as app from "@mage/app";
Add Package
yarn add jsr:@mage/app
yarn dlx jsr add @mage/app
Import symbol
import * as app from "@mage/app";
Add Package
vlt install jsr:@mage/app
Import symbol
import * as app from "@mage/app";
Add Package
npx jsr add @mage/app
Import symbol
import * as app from "@mage/app";
Add Package
bunx jsr add @mage/app
Import symbol
import * as app from "@mage/app";