<page-hero>

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.

<app-hero-links></app-hero-links>
</page-hero>

<stat-strip>

</stat-strip>

<feature-section>

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.

<route-map>

</route-map>
</feature-section>

<feature-section>

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.

<tabs>

<tab>

```ts [server.ts]
import { H3 } from "h3";

const app = new H3();

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

export default app;
```
</tab>

<tab>

```ts [server.ts]
import { Hono } from "hono";

const app = new Hono();

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

export default app;
```
</tab>

<tab>

```ts [server.ts]
import { Elysia } from "elysia";

const app = new Elysia();

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

export default app.compile();
```
</tab>

<tab>

```ts [server.node.ts]
import Express from "express";

const app = Express();

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

export default app;
```
</tab>
</tabs>
</feature-section>

<feature-section>

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!

<deploy-grid>

</deploy-grid>
</feature-section>

<feature-section>

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.

<bar-chart>

</bar-chart>
</feature-section>

<feature-section>

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.

```ts [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 }
);
```
</feature-section>

<feature-grid>

</feature-grid>

<call-to-action>

Start with one command

Scaffold a project, or add the Vite plugin to the app you already have.

<app-hero-links></app-hero-links>
</call-to-action>

<sponsors>

</sponsors>
