DEV Community

Alex Spinov
Alex Spinov

Posted on

Nitro Has a Free Universal Server Engine — Deploy Anywhere With One Codebase

Write your server once. Deploy to Node.js, Cloudflare Workers, Vercel, Deno, Bun, AWS Lambda, or a plain Docker container. Nitro handles the adapter.

What is Nitro?

Nitro is a universal server engine built by the Nuxt team. It powers Nuxt's server-side rendering, but it's also a standalone framework for building server applications that deploy anywhere.

Why Nitro

1. Universal Deployment

// server/api/hello.ts
export default defineEventHandler((event) => {
  return { message: 'Hello from Nitro!' };
});
Enter fullscreen mode Exit fullscreen mode
# Deploy to any platform — zero code changes
NITRO_PRESET=cloudflare-pages npx nitropack build
NITRO_PRESET=vercel npx nitropack build
NITRO_PRESET=node-server npx nitropack build
NITRO_PRESET=deno-server npx nitropack build
NITRO_PRESET=aws-lambda npx nitropack build
NITRO_PRESET=bun npx nitropack build
Enter fullscreen mode Exit fullscreen mode

Same code. Different presets. 15+ deployment targets.

2. File-Based API Routes

server/
├── api/
│   ├── users/
│   │   ├── index.get.ts    → GET /api/users
│   │   ├── index.post.ts   → POST /api/users
│   │   └── [id].get.ts     → GET /api/users/:id
│   └── health.ts           → GET /api/health
├── routes/
│   └── feed.xml.ts         → GET /feed.xml
└── middleware/
    └── auth.ts             → Runs on every request
Enter fullscreen mode Exit fullscreen mode

3. Built-in Caching

export default defineCachedEventHandler(async (event) => {
  const data = await fetchExpensiveData();
  return data;
}, {
  maxAge: 60 * 60, // 1 hour
  staleMaxAge: 60 * 60 * 24, // Serve stale for 24h while revalidating
  swr: true,
});
Enter fullscreen mode Exit fullscreen mode

4. Key-Value Storage

export default defineEventHandler(async (event) => {
  const storage = useStorage();

  // Works with any backend: memory, Redis, Cloudflare KV, S3
  await storage.setItem('user:1', { name: 'Alice' });
  const user = await storage.getItem('user:1');

  return user;
});
Enter fullscreen mode Exit fullscreen mode
// nitro.config.ts
export default defineNitroConfig({
  storage: {
    db: { driver: 'redis', url: 'redis://localhost:6379' },
    assets: { driver: 'cloudflare-kv-binding', binding: 'ASSETS' },
  },
});
Enter fullscreen mode Exit fullscreen mode

5. Auto-Imports

// No imports needed — Nitro auto-imports utilities
export default defineEventHandler(async (event) => {
  const body = await readBody(event);
  const query = getQuery(event);
  const params = event.context.params;

  setCookie(event, 'session', 'abc123');
  setHeader(event, 'X-Custom', 'value');

  return sendRedirect(event, '/dashboard');
});
Enter fullscreen mode Exit fullscreen mode

6. WebSocket Support

// server/api/ws.ts
export default defineWebSocketHandler({
  open(peer) {
    peer.send('Welcome!');
    peer.subscribe('chat');
  },
  message(peer, message) {
    peer.publish('chat', message.text());
  },
  close(peer) {
    peer.unsubscribe('chat');
  },
});
Enter fullscreen mode Exit fullscreen mode

Nitro vs Express vs Hono

Nitro Express Hono
Deploy targets 15+ presets Node.js only Multi (manual)
File routing Built-in Manual Manual
Caching Built-in Manual Manual
Storage Multi-driver Manual Manual
Auto-imports Yes No No
WebSocket Built-in Via ws package Via adapter
TypeScript Native Via setup Native

Getting Started

npx giget@latest nitro my-server
cd my-server
npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

The Bottom Line

Nitro decouples your server code from your deployment target. Write once, deploy to 15+ platforms. If you want server portability without lock-in, Nitro is the engine.


Need data solutions? I build scraping tools. Check my Apify actors or email spinov001@gmail.com.

Top comments (0)