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-cache.md


name: cache description: Cached event handlers, cached functions, SWR, options and invalidation in Nitro

Caching

Nitro's cache layer (powered by ocache) builds on the storage layer. Import helpers from nitro/cache.

v3 note: swr now defaults to false (v2 defaulted to true), and maxAge defaults to 1 second — always set both explicitly for anything you want cached.

Cached handlers

defineCachedHandler works like defineHandler plus a cache-options argument.

import { defineCachedHandler } from "nitro/cache";

export default defineCachedHandler((event) => {
  return "I am cached for an hour";
}, { maxAge: 60 * 60 });

Behavior:

  • Only GET/HEAD are cached (stored under separate entries); other methods and requests with a Range header bypass and call the handler.

  • Auto-manages etag (weak, from body hash), cache-control (synthesized from the enforced lifetime), vary, and x-cache (HIT/STALE/REVALIDATED/MISS) headers, plus 304 Not Modified for conditional requests.

  • Concurrent requests for the same key are deduplicated (handler runs once), bounded by maxResolveTime (30s default).

  • last-modified is never synthesized; a handler-set cache-control is never overwritten.

What the handler can see

On cacheable requests the handler only receives request data covered by the cache key; everything else is stripped so it can't render output the key doesn't distinguish:

  • Headers are stripped unless in varies (includes if-none-match/if-modified-since, handled by Nitro).

  • Query params are stripped unless in allowQuery (default: none; /page and /page?a=1 share one entry).

  • Cookies are stripped unless in allowCookies; set-cookie is dropped from cached responses.

  • authorization/proxy-authorization are stripped unless allowAuthorization is set.

  • host is rewritten to the resolved origin host (part of the key), so multi-host handlers get one entry per host.

Use shouldBypassCache for requests that must reach the handler untouched (not stored).

Cached functions

Cache any async function (e.g. an upstream API call) and reuse it across handlers.

import { defineHandler, type H3Event } from "nitro";
import { defineCachedFunction } from "nitro/cache";

const cachedGHStars = defineCachedFunction(async (repo: string) => {
  const data = await fetch(`https://api.github.com/repos/${repo}`).then((r) => r.json());
  return data.stargazers_count;
}, {
  maxAge: 60 * 60,
  name: "ghStars",
  getKey: (repo: string) => repo,
});

export default defineHandler(async (event) => {
  const { repo } = event.context.params;
  const stars = await cachedGHStars(repo).catch(() => 0);
  return { repo, stars };
});

On edge workers the instance is destroyed after each request. Pass event as the first argument to the cached function (and to getKey) so Nitro can use event.waitUntil for background revalidation; on platforms with no request-carried waitUntil, pass the waitUntil option instead.

Cached values are JSON-serialized — don't return Symbols, Maps, or Sets (use serialize/transform for special shapes). Byte values (Uint8Array/ArrayBuffer) are handled and always returned as Uint8Array.

Caching via route rules

Wrap handlers in caching by glob pattern without touching handler code:

import { defineConfig } from "nitro";

export default defineConfig({
  kv: { redis: { driver: "redis", url: "redis://localhost:6379" } },
  routeRules: {
    "/blog/**": { swr: 3600 },                       // SWR, 1h (swr:true = 1s default)
    "/heavy/**": { cache: { maxAge: 3600, base: "redis" } }, // custom mountpoint
    "/api/realtime/**": { cache: false },            // disable
  },
});

Route-rule handlers use the group nitro/route-rules, and the generated name scopes the entry to the route, method and pattern (unique per process — set an explicit name to share entries across workers/restarts with persistent storage).

Options

Shared (defineCachedHandler + defineCachedFunction)
OptionDefaultDescription
maxAge1Seconds the cache is valid. 0 disables caching.
swrfalseServe stale while revalidating in background.
staleMaxAge—Extra seconds a stale value is served (only with swr). 0 = never stale; unset = no TTL written.
base/cacheStorage base (→ cache: prefix). An array enables multi-tier reads/writes.
nameinferredCache namespace (falls back to a hash of the function source).
groupnitro/handlers / nitro/functionsKey group.
getKey(...args)hashCompute cache key (does not change request narrowing).
integritycode+options hashInvalidate when changed.
getMaxAge(entry)—Derive lifetime per entry from the resolved value.
maxResolveTime30Deadline (s) for one shared resolution.
storagecache storageOverride the backend for this handler/function.
waitUntil(promise)—Hand background work to the host runtime.
shouldInvalidateCache / shouldBypassCache—Per-call predicates.
onError(err)logCustom error handling.
Handler-only

varies (header names in the key / kept on request), allowQuery (boolean \| string[]), allowCookies (string[], emits Vary: Cookie), allowAuthorization, sendCacheControl (default true; false = server-only caching), cacheStatusHeader (default X-Cache), stream, maxBodySize, headersOnly, shouldCache(entry).

Function-only

transform(entry, ...args) (read-side, entry.status = hit/stale/revalidated/miss), serialize(entry, ctx) (write-side), validate(entry, ctx).

What gets cached

Only responses with status 200/203/301/308, a body, no cache-control opt-out (no-store/private/no-cache/zero shared lifetime), and no Vary: * (or Vary naming a header outside the key) are stored. Failing responses are still returned, just not stored — and get no synthesized cache-control. must-revalidate only disables SWR for that response.

Cache keys & invalidation

Key pattern: `${base}:${group}:${name}:${getKey(...args)}.json` (group/name are sanitized; a hash is appended if characters were removed).

Cached functions expose on-demand methods:

await cachedGHStars("unjs/nitro");              // populate
await cachedGHStars.expire("unjs/nitro");       // mark stale (SWR: served while refreshing)
await cachedGHStars.invalidate("unjs/nitro");   // remove entirely
await cachedGHStars.resolveKeys("unjs/nitro");  // storage key(s) for these args

defineCachedHandler returns a plain handler and does not expose these methods — move expensive work into a defineCachedFunction (called from a plain defineHandler) and invalidate the function when you need on-demand invalidation.

Cache storage

Entries live under the cache: prefix. By default they sit in the in-memory root storage (not persisted). Configure a persistent backend by mounting a cache point via the kv option (see core-storage):

import { defineConfig } from "nitro";

export default defineConfig({
  kv: { cache: { driver: "redis" /* options */ } },
  $development: { kv: { cache: { driver: "fs", base: "./.data/cache" } } },
});

Key Points

  • Import from nitro/cache; swr and maxAge both default small — set them explicitly.

  • defineCachedFunction caches reusable logic (and supports .invalidate()/.expire()); defineCachedHandler caches whole responses.

  • On edge, always thread event through cached functions for waitUntil-backed refresh.

  • Persist cache by mounting a cache point via the kv config option (not the removed storage).

<!-- Source references: - https://nitro.build/docs/cache - https://nitro.build/docs/routing#route-rules - https://ocache.unjs.io -->

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