.agents/skills/nitro-server-expert/SKILL.md
Expert guide for building Nitro server applications. Use when implementing Nitro handlers, configuring presets, setting up routing, working with middleware, tasks, storage, database, WebSocket, or deploying to any supported platform (Cloudflare, Deno, Node.js, Netlify, Zephyr, AWS Amplify, etc.). Covers filesystem routing, route rules, code splitting, presets, hooks, and runtime behavior.
npx skillsauth add em-jones/staccato-toolkit nitro-server-expertInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Expert-level guidance for building, configuring, and deploying Nitro server applications. Nitro is a universal server framework that compiles to any JavaScript runtime — Node.js, Deno, Cloudflare Workers, WinterJS, and more — via a preset system.
Nitro follows these key principles:
routes/ and api/ directories automatically become HTTP endpoints. Route patterns use [param] for dynamic segments and [...slug] for catch-all.H3Event object.#nitro/ and #imports virtual module namespaces for runtime APIs.build:before, compiled, close.// nitro.config.ts
import { defineNitroConfig } from "nitro/config";
export default defineNitroConfig({
preset: "node-server", // auto-detected in most environments
serverDir: "./server",
imports: {
dirs: ["./utils"],
},
});
// routes/api/hello.ts
import { defineHandler } from "nitro";
export default defineHandler((event) => {
return { message: `Hello ${event.url.pathname}!` };
});
// routes/users.get.ts — GET only
export default defineHandler(async (event) => {
return { users: [] };
});
// routes/users.post.ts — POST only
export default defineHandler(async (event) => {
const body = await event.req.json();
return { created: true, body };
});
Load detailed guidance based on context:
| Topic | Reference | Load When |
| ------------------ | ----------------------------- | ------------------------------------------------------------------------------------- |
| Handlers | references/handlers.md | Writing event handlers, cached handlers, middleware, error handling |
| Deployment Presets | references/presets.md | Deploying to Cloudflare, Deno, Node.js, Netlify, Zephyr, AWS Amplify, or any platform |
| Routing | references/routing.md | File-based routing, dynamic routes, middleware, route rules, code splitting |
| Configuration | references/configuration.md | nitro.config.ts options, build settings, output dirs, experimental features |
| Runtime Behavior | references/runtime.md | nitroApp lifecycle, hooks, tasks, storage, database, WebSocket, virtual modules |
| Plugins | references/plugins.md | Creating plugins, runtime hooks, error monitoring, lifecycle extension |
| Assets | references/assets.md | Public assets, server assets, compression, custom asset directories |
| Deployment | references/deployment.md | Platform-specific deployment, environment variables, production checklist |
| Testing | references/testing.md | Testing Nitro handlers, dev vs prod testing, Vitest integration |
| Import | Purpose |
| ---------------------------------------------------- | ------------------------------------- |
| import { defineHandler } from "nitro" | Typed handler factory |
| import { defineHandler } from "nitro/h3" | H3-specific handler with event typing |
| import { defineNitroConfig } from "nitro/config" | Config factory |
| import { useStorage } from "nitro/storage" | Key-value storage access |
| import { useDatabase } from "nitro/database" | Database connector (experimental) |
| import { useNitroApp } from "nitro/app" | Runtime nitro app instance |
| import { useNitroHooks } from "nitro/app" | Runtime hooks access |
| import { defineCachedHandler } from "nitro/cache" | Cached handler factory |
| import { defineCachedFunction } from "nitro/cache" | Cached function factory |
| import { definePlugin } from "nitro" | Plugin factory |
| import { defineTask } from "nitro/task" | Task definition factory |
Handlers can return:
application/jsontext/plainResponse objects → sent as-is (full control)ReadableStream → streaming responsesnull/undefined → 204 No Content| Variable | Purpose |
| -------------------- | --------------------------- |
| NITRO_PRESET | Override deployment preset |
| NITRO_PORT | Server port (default: 3000) |
| NITRO_HOST | Server host |
| NITRO_SSL_CERT | TLS certificate |
| NITRO_SSL_KEY | TLS private key |
| NITRO_APP_BASE_URL | Application base URL |
| DEBUG | Enable debug mode |
defineHandler() for type inference on handlersapi/ or routes/ directories under serverDirevent.url for URL access (standard URL object)event.context.params for route parametersevent.req for the raw Request object01.auth.ts)event as first arg to defineCachedFunction in edge workersnitro subpaths not documented in the public APIprocess.env for runtime config — use useRuntimeConfig() insteadimport { defineHandler } from "nitro";
import { useDatabase } from "nitro/database";
export default defineHandler(async () => {
const db = useDatabase();
const { rows } = await db.sql`SELECT * FROM users`;
return { rows };
});
import { defineHandler } from "nitro/h3";
import { useStorage } from "nitro/storage";
export default defineHandler(async (event) => {
const storage = useStorage("my-store");
await storage.setItem("key", { data: "value" });
return await storage.getItem("key");
});
import { defineCachedHandler } from "nitro/cache";
export default defineCachedHandler(
(event) => {
return { data: "cached for 1 hour" };
},
{ maxAge: 60 * 60, swr: true },
);
// In nitro.config.ts
export default defineNitroConfig({
features: { websocket: true },
});
// nitro.config.ts
export default defineNitroConfig({
errorHandler: "~/error",
});
// error.ts
export default defineNitroErrorHandler((error, event) => {
return new Response(`[custom] ${error.message}`, { status: error.status || 500 });
});
// plugins/monitoring.ts
import { definePlugin } from "nitro";
export default definePlugin((nitroApp) => {
nitroApp.hooks.hook("error", async (error, { event, tags }) => {
console.error(`${event?.path} Error:`, error);
});
nitroApp.hooks.hook("close", async () => {
// Cleanup resources
});
});
// tasks/db/migrate.ts
export default defineTask({
meta: { name: "db:migrate", description: "Run database migrations" },
run({ payload, context }) {
console.log("Running DB migration...");
return { result: "Success" };
},
});
tools
<!--VITE PLUS START--> # Using Vite+, the Unified Toolchain for the Web This project is using Vite+, a unified toolchain built on top of Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, and Vite Task. Vite+ wraps runtime management, package management, and frontend tooling in a single global CLI called `vp`. Vite+ is distinct from Vite, but it invokes Vite through `vp dev` and `vp build`. ## Vite+ Workflow `vp` is a global binary that handles the full development lifecycle. Run `vp help` to pr
development
Guide for building performant data tables. Uses tanstack-table for table logic (sorting, filtering, pagination) and tanstack-virtual for rendering large datasets efficiently.
development
Expert guidance for building observable, expressive, and fault-tolerant TypeScript applications using the effect-ts/effect ecosystem. Covers Effect<A, E, R> type, error management, dependency injection via Layers, observability (logging, metrics, tracing), concurrency with Fibers, retry/scheduling, Schema validation, Streams, and Sinks.
tools
Complete E2E (end-to-end) and integration testing skill for TypeScript/NestJS projects using Jest, real infrastructure via Docker, and GWT pattern. ALWAYS use this skill when user needs to: **SETUP** - Initialize or configure E2E testing infrastructure: - Set up E2E testing for a new project - Configure docker-compose for testing (Kafka, PostgreSQL, MongoDB, Redis) - Create jest-e2e.config.ts or E2E Jest configuration - Set up test helpers for database, Kafka, or Redis - Configure .env.e2e environment variables - Create test/e2e directory structure **WRITE** - Create or add E2E/integration tests: - Write, create, add, or generate e2e tests or integration tests - Test API endpoints, workflows, or complete features end-to-end - Test with real databases, message brokers, or external services - Test Kafka consumers/producers, event-driven workflows - Working on any file ending in .e2e-spec.ts or in test/e2e/ directory - Use GWT (Given-When-Then) pattern for tests **REVIEW** - Audit or evaluate E2E tests: - Review existing E2E tests for quality - Check test isolation and cleanup patterns - Audit GWT pattern compliance - Evaluate assertion quality and specificity - Check for anti-patterns (multiple WHEN actions, conditional assertions) **RUN** - Execute or analyze E2E test results: - Run E2E tests - Start/stop Docker infrastructure for testing - Analyze E2E test results - Verify Docker services are healthy - Interpret test output and failures **DEBUG** - Fix failing or flaky E2E tests: - Fix failing E2E tests - Debug flaky tests or test isolation issues - Troubleshoot connection errors (database, Kafka, Redis) - Fix timeout issues or async operation failures - Diagnose race conditions or state leakage - Debug Kafka message consumption issues **OPTIMIZE** - Improve E2E test performance: - Speed up slow E2E tests - Optimize Docker infrastructure startup - Replace fixed waits with smart polling - Reduce beforeEach cleanup time - Improve test parallelization where safe Keywords: e2e, end-to-end, integration test, e2e-spec.ts, test/e2e, Jest, supertest, NestJS, Kafka, Redpanda, PostgreSQL, MongoDB, Redis, docker-compose, GWT pattern, Given-When-Then, real infrastructure, test isolation, flaky test, MSW, nock, waitForMessages, fix e2e, debug e2e, run e2e, review e2e, optimize e2e, setup e2e