Build Servers

Nitro builds production-ready servers that run anywhere.

Write API routes, then deploy the same codebase to Node.js, Bun, Deno, or serverless, with zero configuration.

3.8 kB
Gzipped output
0
Runtime deps
25+
Deploy targets
~50 ms
Cold start

Routing

Files in, Routes out

Drop a file in routes/ and it becomes a route. Append the HTTP method to the filename to scope it, nest folders for path params, and wrap a folder in parentheses to group routes without touching the URL.
  • Routes are compiled no runtime router ships in the bundle
  • Dynamic params, wildcards and per-method files
  • Route groups organize files without changing URLs
Routing docs
routes/
  • hello.get.tsGET/hello
  • hello.post.tsPOST/hello
  • api/test.tsANY/api/test
  • api/[org]/[repo].tsANY/api/:org/:repo
  • (admin)/users.tsANY/users

Server entry

Bring your own framework

Any framework that speaks the Web fetch(request): Response interface can be your server entry export it from server.ts and it runs for every request before routes are matched. Node-style (req, res) frameworks work too: name the file server.node.ts and Nitro adapts it.
Server entry docs
server.ts
import { H3 } from "h3";

const app = new H3();

app.get("/", () => "⚡️ Hello from H3!");

export default app;
server.ts
import { Hono } from "hono";

const app = new Hono();

app.get("/", (c) => c.text("🔥 Hello from Hono!"));

export default app;
server.ts
import { Elysia } from "elysia";

const app = new Elysia();

app.get("/", () => "🦊 Hello from Elysia!");

export default app.compile();
server.node.ts
import Express from "express";

const app = Express();

app.use("/", (_req, res) => {
  res.send("Hello from Express with Nitro!");
});

export default app;

Deploy

One codebase, every platform

The same server builds for Node.js, Deno, Bun, edge workers and serverless functions. Nitro emits the output format each host expects, so moving between them requires no code changes!
  • Providers are auto-detected in CI no adapter to install
  • Switch targets with a single `preset` option
  • Compatibility dates keep provider behavior stable over time
All deploy targets

Output

Small enough to read

A production build of a minimal Nitro server is three files with nothing to install alongside them. Dependencies are bundled and tree-shaken, so what you deploy is the code you wrote plus the little that runs it.
Build your first server
Production server output
Unminified16.2 kB
Minified8.8 kB
Minified + gzipped3.8 kB

Cache

Caching that follows your storage

Wrap a handler or any async function and Nitro caches its result on the same storage layer your app already uses memory in development, then Redis, Cloudflare KV, a Vercel Blob store or the filesystem in production. Same code, different backend.
  • Stale-while-revalidate responses by default
  • ETag, last-modified and 304 handling out of the box
  • Concurrent requests for one key share a single invocation
Caching docs
routes/stars.ts
import { defineCachedHandler } from "nitro/cache";

export default defineCachedHandler(
  async () => {
    const res = await fetch("https://api.github.com/repos/nitrojs/nitro");
    const { stargazers_count } = await res.json();
    return { stars: stargazers_count };
  },
  { maxAge: 60 * 60 }
);

Start with one command

Scaffold a project, or add the Vite plugin to the app you already have.
npx create-nitro-app

Nitro  builds full-stack servers that deploy anywhere.