Building a backend that works on Vercel, Cloudflare Workers, AWS Lambda, AND a traditional server? Nitro compiles your code to run everywhere — write once, deploy anywhere.
What Is Nitro?
Nitro is a universal server engine from the UnJS ecosystem. It powers Nuxt 3's server, but works standalone too. Write your API once — Nitro adapts it to any deployment target.
Quick Start
npx giget@latest nitro my-api
cd my-api && npm install && npm run dev
// routes/hello.ts
export default defineEventHandler(() => {
return { message: 'Hello from Nitro!' };
});
// GET /hello → { "message": "Hello from Nitro!" }
File-Based API Routing
routes/
index.ts → GET /
users/
index.get.ts → GET /users
index.post.ts → POST /users
[id].get.ts → GET /users/:id
[id].put.ts → PUT /users/:id
[id].delete.ts → DELETE /users/:id
health.ts → GET /health
Request Handling
// routes/users/index.post.ts
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const query = getQuery(event);
const id = getRouterParam(event, 'id');
const header = getHeader(event, 'authorization');
// Validation
if (!body.email) {
throw createError({ statusCode: 400, message: 'Email required' });
}
const user = await db.createUser(body);
return user;
});
Deploy Anywhere
# Build for different targets
NITRO_PRESET=vercel npm run build
NITRO_PRESET=cloudflare npm run build
NITRO_PRESET=aws-lambda npm run build
NITRO_PRESET=node-server npm run build
NITRO_PRESET=deno npm run build
NITRO_PRESET=bun npm run build
Same code. Different output. Zero changes needed.
Built-In Features
Storage (KV, File, Redis)
// Use unified storage API
const storage = useStorage();
await storage.setItem('user:123', { name: 'John' });
const user = await storage.getItem('user:123');
// Configure backend in nitro.config.ts
export default defineNitroConfig({
storage: {
redis: { driver: 'redis', url: 'redis://localhost:6379' }
}
});
Caching
// routes/api/stats.ts
export default defineCachedEventHandler(async () => {
const stats = await fetchExpensiveStats();
return stats;
}, { maxAge: 60 * 10 }); // Cache for 10 minutes
Scheduled Tasks
// tasks/cleanup.ts
export default defineTask({
meta: { description: 'Clean up old sessions' },
run() {
return db.deleteExpiredSessions();
}
});
Why Nitro
| Feature | Nitro | Express | Fastify |
|---|---|---|---|
| Deploy targets | 15+ | Node only | Node only |
| File routing | Built-in | Manual | Plugin |
| TypeScript | Native | Manual setup | Plugin |
| Auto-imports | Yes | No | No |
| Hot reload | Built-in | nodemon | Manual |
| Caching | Built-in | Manual | Manual |
| Storage | Unified API | Manual | Manual |
Get Started
- Documentation
- GitHub — 6K+ stars
- UnJS ecosystem
Building APIs that need web data? My Apify actors extract structured data from any website — feed it to your Nitro API. Custom solutions: spinov001@gmail.com
Top comments (0)