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://mp-staging.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.

Download ZIP

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