Nitro is the server engine that powers Nuxt 3 — but it works standalone too. Write server code once, deploy to Node.js, Deno, Bun, Cloudflare Workers, AWS Lambda, Vercel, Netlify, or any serverless platform.
Why Nitro?
- Universal — same code deploys to 20+ platforms
- Auto-imports — no import statements needed
- File-based routing — like Next.js but for APIs
- Built-in caching — SWR, storage drivers
- Hot reload — instant dev server refresh
Quick Start
npx giget@latest nitro my-api
cd my-api
npm install
npm run dev # http://localhost:3000
File-Based API Routes
// server/routes/hello.ts
export default defineEventHandler(() => {
return { message: 'Hello from Nitro!' };
});
// GET /hello → {"message": "Hello from Nitro!"}
// server/routes/users/index.get.ts
export default defineEventHandler(async () => {
const users = await db.select().from(usersTable);
return users;
});
// GET /users
// server/routes/users/index.post.ts
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const user = await db.insert(usersTable).values(body).returning();
return user;
});
// POST /users
// server/routes/users/[id].get.ts
export default defineEventHandler(async (event) => {
const id = getRouterParam(event, 'id');
const user = await db.select().from(usersTable).where(eq(usersTable.id, id));
if (!user.length) throw createError({ statusCode: 404, message: 'Not found' });
return user[0];
});
// GET /users/:id
Middleware
// server/middleware/auth.ts
export default defineEventHandler((event) => {
const token = getHeader(event, 'authorization');
if (!token && event.path.startsWith('/api/protected')) {
throw createError({ statusCode: 401, message: 'Unauthorized' });
}
});
// server/middleware/cors.ts
export default defineEventHandler((event) => {
setHeaders(event, {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
});
});
Caching
// server/routes/cached-data.ts
export default defineCachedEventHandler(async () => {
// This result is cached!
const data = await fetchExpensiveData();
return data;
}, {
maxAge: 60 * 60, // 1 hour
staleMaxAge: 60 * 60 * 24, // SWR: serve stale for 24h
swr: true,
});
Storage
// server/routes/kv.ts
export default defineEventHandler(async (event) => {
const storage = useStorage('data');
// Set
await storage.setItem('user:1', { name: 'Alice' });
// Get
const user = await storage.getItem('user:1');
// List keys
const keys = await storage.getKeys('user:');
return { user, keys };
});
Deploy to Any Platform
// nitro.config.ts
export default defineNitroConfig({
// Change this ONE line to deploy anywhere
preset: 'cloudflare-pages', // or: 'vercel', 'netlify', 'node-server', 'deno', 'bun', 'aws-lambda'
});
npm run build # Builds for target platform
Key Features
| Feature | Details |
|---|---|
| Routing | File-based, method-based |
| Presets | 20+ deployment targets |
| Caching | SWR, storage-backed |
| Storage | KV, FS, Redis, S3, Cloudflare KV |
| WebSocket | Built-in support |
| Tasks | Background tasks, scheduled |
Resources
Building APIs? Check my Apify actors or email spinov001@gmail.com.
Top comments (0)