Generated banner for Nitro
Generated logo for Nitro

Nitro

Anthony FuCommunityCreated by Anthony Fu

  • Skill
  • Tool integration
  • Software development
  • MIT
  • No issues found

From the author

Nitro is the framework-agnostic server toolkit (powering Nuxt) for building and deploying web servers anywhere. Use when working with nitro.config, server routes/event handlers, route rules, caching, storage, tasks, websockets, or deploying to Node/Bun/Deno/Cloudflare/Vercel.
— the description by Anthony Fu

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

Nitro is a server toolkit designed to build and deploy web servers that run on Node.js, Bun, Deno, and various cloud platforms like Cloudflare, Vercel, and Netlify. It provides a unified codebase for server development, featuring filesystem-based routing, a built-in KV storage layer, caching mechanisms, and support for tasks, WebSockets, and OpenAPI documentation. Nitro v3 introduces significant changes including a package rename, the removal of auto-imports, and a shift toward web-standard H3 v2 APIs.

What it does

  • Provides filesystem-based routing with H3 v2 event handlers.
  • Manages server configuration and runtime settings via nitro.config.ts.
  • Handles caching and storage using an unstorage-based KV layer.
  • Supports on-demand and scheduled tasks, WebSockets, and SSE.
  • Generates OpenAPI specifications automatically from route metadata.
  • Enables deployment to multiple runtimes and platforms through presets.

When to use it

  • When building a web server that needs to be portable across different deployment environments.
  • When you require a unified toolkit for handling routing, storage, and caching in a server project.
  • When migrating existing server projects from Nitro v2 to v3.
  • When you need to implement server-side tasks, WebSockets, or OpenAPI documentation.

Advantages

  • Framework-agnostic design allows for use with or without other frameworks.
  • Deployment-agnostic architecture supports a wide range of runtimes and cloud providers.
  • Unified storage and caching layer simplifies data management.
  • Declarative route rules for handling redirects, headers, and CORS.
  • Built-in support for modern web standards via H3 v2.

Usage examples

“How do I define a basic server route in Nitro v3?”
You create a file in your server directory and export a handler using defineHandler from the nitro package.
“How do I access KV storage in my Nitro server?”
You use the useKV function imported from nitro/kv to interact with your configured storage mount points.
“What is the correct way to import Nitro utilities in v3?”
You must use explicit imports from specific subpaths like nitro, nitro/kv, or nitro/h3, as auto-imports are no longer supported.
“How do I configure public assets in Nitro?”
You define a publicAssets array in your nitro.config.ts file, specifying the directory and base URL for your assets.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/antfu/nitro/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip nitro.zip -d .agents/skills

Documentation by Anthony Fu

The skill is based on Nitro v3 (beta, 3.0.260903), generated at 2026-09-25.

Nitro is a framework-agnostic, deployment-agnostic server toolkit powered by H3 v2, unstorage, and Vite/Rolldown/Rollup. It powers Nuxt and works standalone. From one codebase it builds optimized output for Node.js, Bun, Deno, Cloudflare, Vercel, Netlify, and more.

Key capabilities:

  • Filesystem routing with H3 v2 event handlers, dynamic params, and method suffixes.

  • Route rules for declarative caching, headers, redirects, proxying, and CORS.

  • Caching layer (cached handlers/functions, SWR) on top of the unstorage KV layer.

  • Runtime config overridable via NITRO_* env vars.

  • Tasks (on-demand + scheduled/cron), WebSockets/SSE, a SQL database layer, and OpenAPI auto-docs.

  • Plugins & lifecycle hooks, custom renderer/server entry, and portable deployment presets.

Key v3 changes (vs. nitropack v2): the package is renamed nitropack → nitro with H3 v2 (web-standard Request/Response); auto-imports are removed (import everything explicitly); directory scanning is opt-in via serverDir; useStorage → useKV (nitro/kv) and the storage config option → kv; cache swr now defaults to false. If unsure about v2-vs-v3 APIs, read advanced-migration first.

Core

TopicDescriptionReference
RoutingFile-based routes, defineHandler, params, middleware, route rules, errorscore-routing
Configurationnitro.config.ts, defineConfig, key options, runtime configcore-configuration
Storageunstorage KV, mount points, drivers, dynamic mountscore-storage
CachedefineCachedHandler, defineCachedFunction, SWR, invalidationcore-cache
AssetsPublic assets, compression, server assets via storagecore-assets
RenderingRenderer (HTML/SSR), server entry, framework integrationcore-rendering

Features

TopicDescriptionReference
Plugins & HooksdefinePlugin, runtime lifecycle hooks, error capturefeatures-plugins
TasksOn-demand & scheduled (cron) tasks, runTaskfeatures-tasks
WebSocket & SSEdefineWebSocketHandler, pub/sub, namespaces, event streamsfeatures-websocket
DatabaseBuilt-in SQL layer via db0, useDatabase, connectorsfeatures-database
OpenAPIAuto spec from defineRouteMeta, Scalar/Swagger UIsfeatures-openapi

Advanced / Deployment

TopicDescriptionReference
Deployment PresetsRuntimes & providers, compatibility dates, platform integrationdeploy-presets
v2 → v3 MigrationPackage rename, nitro/* imports, H3 v2 API, preset changesadvanced-migration

Files

references/core-routing.md


name: routing description: File-based routing, event handlers, dynamic params, middleware, and route rules in Nitro

Routing & Event Handlers

Nitro maps files in routes/ and api/ to HTTP routes at build time (no runtime router). Handlers receive an H3 v2 event and should return the response body or throw an error.

v3: filesystem routing only runs when serverDir (or scanDirs) is set — no directories are scanned by default. Auto-imports are removed, so import defineHandler/HTTPError explicitly.

Event handlers

import { defineHandler } from "nitro";

export default defineHandler((event) => {
  return { hello: "world" };
});

defineHandler gives type inference. A plain (event) => ... function also works. The event is web-standard based:

event.req            // web Request
event.res            // response init (headers, status)
event.url            // URL object (event.url.pathname, event.url.searchParams)
event.path           // request path
event.method         // HTTP method
event.context        // mutable per-request context (params, custom data)
event.context.params // route params

Read the body with native Request methods (H3 v2 dropped readBody):

const json = await event.req.json();
const text = await event.req.text();
const form = await event.req.formData();

Filesystem routing

Files in api/ (served under /api) or routes/ (served under /) become routes. One handler per file.

routes/
  hello.ts            -> /hello
  api/
    test.ts           -> /api/test
    [org]/
      [repo]/
        index.ts      -> /api/:org/:repo
        issues.ts     -> /api/:org/:repo/issues
HTTP method suffix

Append the method to match only that verb (get, post, put, delete, patch, head, options, query, connect, trace):

import { defineHandler } from "nitro";

export default defineHandler(async (event) => {
  const body = await event.req.json();
  return { created: body };
});
Dynamic params
export default defineHandler((event) => {
  const { name } = event.context.params!;
  return `Hello ${name}!`;
});
  • Multiple params: each as its own folder/segment [a]/[b] (not in one filename).

  • Catch-all: [...name].ts captures the rest of the path (includes /).

  • Global catch-all: [...].ts matches all otherwise-unmatched routes; its wildcard is on event.context.params._. It chains before the server entry and renderer.

Route groups & environment handlers
  • Parenthesized folders (admin)/ group files without affecting the URL.

  • Suffix .dev, .prod, or .prerender (after the method suffix) to include a handler only in that build: test.get.prod.ts.

  • ignore: ["routes/**/_*"] config excludes files from scanning.

Middleware

Files in middleware/ run on every request before route matching. They modify the event and must not return (returning ends the request).

import { defineHandler } from "nitro";

export default defineHandler((event) => {
  event.context.user = { name: "Nitro" };
});

Control execution order with numeric prefixes (1.logger.ts, 2.auth.ts — pad to 01. etc. beyond 9 to keep string sort correct). Scope manually with event.url.pathname, or register route-scoped middleware in config (keep the file outside middleware/ so it isn't also registered globally):

export default defineConfig({
  handlers: [
    { route: "/api/**", handler: "./utils/api-auth.ts", middleware: true },
  ],
});

Programmatic routes

Register handlers/middleware in config in addition to (or instead of) the filesystem:

export default defineConfig({
  routes: {
    "/api/hello": "./routes/api/hello.ts",
    "/api/custom": { handler: "./routes/custom.ts", method: "POST", lazy: true },
  },
  handlers: [
    { route: "/blog/**", handler: "./handlers/blog.ts", method: "get" },
  ],
});

Handler options: handler, method, lazy, middleware, format ("web" | "node"), env.

Error handling

Throw HTTPError (replaces v2 createError):

import { defineHandler, HTTPError } from "nitro";

export default defineHandler((event) => {
  const user = findUser(event.context.params!.id);
  if (!user) {
    throw new HTTPError({ status: 404, message: "User not found" });
  }
  return user;
});

HTTPError has several forms: new HTTPError("msg", { status: 400 }), HTTPError.status(400, "Bad Request"), or the full object form. Any other thrown value is treated as unhandled (always 500, message/stack hidden).

In dev, browsers (Accept: text/html) get an HTML error page; production always returns JSON ({ error, status, message, data }). Customize with the errorHandler config (a path or array of paths) to a module exporting defineErrorHandler((error, event) => Response) from nitro. Handlers run in order (first response wins; built-in default is always appended); devErrorHandler overrides dev-only rendering.

Route rules

Apply per-route behavior (caching, headers, redirects, proxy, CORS) by glob pattern (rou3 syntax). Rules merge least-specific to most-specific; set a rule to false to disable an inherited one. When cache is set, matching handlers are auto-wrapped with defineCachedHandler.

import { defineConfig } from "nitro";

export default defineConfig({
  routeRules: {
    "/blog/**": { swr: 600 },                   // stale-while-revalidate w/ maxAge
    "/api/data/**": { cache: { maxAge: 60 } },  // full cache options
    "/api/realtime/**": { cache: false },       // disable caching
    "/assets/**": { headers: { "cache-control": "s-maxage=0" } },
    "/api/public/**": { cors: true },           // permissive CORS defaults
    "/api/v1/**": { cors: { origin: ["https://app.example.com"], credentials: true } },
    "/old-page": { redirect: "/new-page" },     // 307 by default
    "/legacy": { redirect: { to: "https://example.com/", status: 308 } },
    "/old-blog/**": { redirect: "https://blog.example.com/**" }, // wildcard preserves suffix
    "/proxy/**": { proxy: "https://api.example.com/**" },
    "/about": { prerender: true },
    "/isr/**": { isr: 60 },                      // Vercel ISR
  },
});

Route rule keys: headers, redirect, proxy, cors, cache, swr, static, prerender, isr. swr: true = cache: { swr: true } (1s default maxAge); swr: <n> adds maxAge: <n>. Rules can also be supplied via runtimeConfig.nitro.routeRules for env-var overrides without rebuilding.

No auth/basicAuth route rule. Auth needs executable logic → use middleware. For a single route use h3's basicAuth from nitro/h3 in the handler's middleware array:

import { defineHandler } from "nitro";
import { basicAuth } from "nitro/h3";
export default defineHandler({
  middleware: [basicAuth({ username: "admin", password: "secret" })],
  handler: (event) => `Hello, ${event.context.basicAuth?.username}!`,
});
Method-scoped rules

Prefix a key with an uppercase HTTP method + space to scope it; unprefixed keys apply to every method and are merged underneath:

routeRules: {
  "/api/**": { headers: { "x-api": "true" } },     // every method
  "POST /api/**": { headers: { "x-write": "true" } },
  "GET /feed": { swr: 600 },
}

Platform-native static config (Netlify/Cloudflare _headers/_redirects, Vercel config.json) does not split by method — prefer method-agnostic keys for headers/redirect/proxy you expect emitted statically. Do not combine prerender and isr on the same route.

Key Points

  • Handlers return the body or throw; H3 v1 send* helpers are gone.

  • Use event.req.json()/text()/formData() instead of v2 readBody.

  • Params live on event.context.params (unnamed catch-all on params._).

  • Each route handler is a separate code-split chunk (set inlineDynamicImports: true to bundle into one file).

  • Route rules wrap matching handlers in caching, proxying, redirects, and CORS without handler code — auth goes in middleware.

<!-- Source references: - https://nitro.build/docs/routing - https://nitro.build/docs/lifecycle - https://nitro.build/config -->

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
Anthony Fu
Publisher
Anthony Fu (Community)
Source
antfu/skills · skills/nitro · commit f63e9ec
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE.md)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Anthony Fu or Anthony Fu.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download nitro.zip