Skills nitro

install
source · Clone the upstream repo
git clone https://github.com/TerminalSkills/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/TerminalSkills/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/nitro" ~/.claude/skills/terminalskills-skills-nitro && rm -rf "$T"
manifest: skills/nitro/SKILL.md
source content

Nitro

Overview

Nitro is a universal server engine — write your server code once, deploy it anywhere. Node.js, Deno, Bun, Cloudflare Workers, Vercel Edge, AWS Lambda, Netlify — same code, zero config changes. It powers Nuxt's server routes but works standalone for any API or full-stack app. File-based routing, built-in KV storage, auto-imports, and hot reload.

When to Use

  • Building APIs that need to deploy to multiple platforms
  • Edge-first applications (Cloudflare Workers, Vercel Edge)
  • Server-side companion for a frontend framework (not just Nuxt)
  • Need built-in caching, storage, and task scheduling without external packages
  • Migrating Express/Fastify to a platform-agnostic solution

Instructions

Setup

npx giget@latest nitro my-server
cd my-server
npm install
npm run dev

File-Based API Routes

server/
├── routes/
│   ├── index.ts            # GET /
│   ├── users/
│   │   ├── index.get.ts    # GET /users
│   │   ├── index.post.ts   # POST /users
│   │   └── [id].get.ts     # GET /users/:id
│   └── health.ts           # GET /health
├── middleware/
│   └── auth.ts             # Runs before every request
├── plugins/
│   └── database.ts         # Initialization logic
└── utils/
    └── db.ts               # Shared utilities (auto-imported)
// server/routes/users/index.get.ts — List users
export default defineEventHandler(async (event) => {
  const query = getQuery(event);
  const page = Number(query.page) || 1;
  const limit = Math.min(Number(query.limit) || 20, 100);

  const users = await db.user.findMany({
    skip: (page - 1) * limit,
    take: limit,
  });

  return { users, page, limit };
});

// server/routes/users/index.post.ts — Create user
export default defineEventHandler(async (event) => {
  const body = await readBody(event);

  if (!body.email || !body.name) {
    throw createError({ statusCode: 400, message: "Email and name required" });
  }

  const user = await db.user.create({ data: body });
  setResponseStatus(event, 201);
  return user;
});

// server/routes/users/[id].get.ts — Get user by ID
export default defineEventHandler(async (event) => {
  const id = getRouterParam(event, "id");
  const user = await db.user.findUnique({ where: { id } });

  if (!user) {
    throw createError({ statusCode: 404, message: "User not found" });
  }

  return user;
});

Middleware

// server/middleware/auth.ts — Auth middleware for all routes
export default defineEventHandler(async (event) => {
  // Skip auth for public routes
  const url = getRequestURL(event);
  if (url.pathname === "/health" || url.pathname.startsWith("/auth/")) return;

  const token = getHeader(event, "authorization")?.replace("Bearer ", "");
  if (!token) {
    throw createError({ statusCode: 401, message: "Unauthorized" });
  }

  const user = await verifyToken(token);
  event.context.user = user;
});

Built-in Storage (KV)

// server/routes/cache/[key].ts — KV storage (works on every platform)
export default defineEventHandler(async (event) => {
  const key = getRouterParam(event, "key")!;

  if (event.method === "GET") {
    const value = await useStorage("cache").getItem(key);
    if (!value) throw createError({ statusCode: 404 });
    return value;
  }

  if (event.method === "PUT") {
    const body = await readBody(event);
    await useStorage("cache").setItem(key, body);
    return { ok: true };
  }
});

Deploy to Any Platform

# Build for different targets
NITRO_PRESET=cloudflare-pages npx nitro build
NITRO_PRESET=vercel npx nitro build
NITRO_PRESET=netlify npx nitro build
NITRO_PRESET=node-server npx nitro build
NITRO_PRESET=deno-server npx nitro build
NITRO_PRESET=bun npx nitro build
NITRO_PRESET=aws-lambda npx nitro build

Examples

Example 1: Build a REST API that deploys to Cloudflare Workers

User prompt: "Create a REST API with CRUD routes that runs on Cloudflare Workers edge."

The agent will create a Nitro project with file-based CRUD routes, middleware for auth, Cloudflare KV for storage, and deploy config for Workers.

Example 2: API with caching and scheduled tasks

User prompt: "Build an API that caches expensive database queries and refreshes them every hour."

The agent will use Nitro's built-in storage for caching, defineTask for scheduled refreshes, and route-level cache headers.

Guidelines

  • File naming = HTTP method
    users.get.ts
    ,
    users.post.ts
    ,
    users.delete.ts
  • [param]
    for dynamic routes
    [id].get.ts
    captures
    :id
  • useStorage()
    is universal
    — KV that works on every platform (memory, Redis, Cloudflare KV)
  • createError()
    for HTTP errors
    — structured error responses with status codes
  • Auto-imports
    defineEventHandler
    ,
    readBody
    ,
    getQuery
    are available without imports
  • Middleware runs on every request — use path checks to skip public routes
  • NITRO_PRESET
    for deployment
    — one codebase, 15+ deployment targets
  • event.context
    for request state
    — pass data between middleware and handlers