DEV Community

Alex Spinov
Alex Spinov

Posted on

Nitro Has a Free API — The Universal Server Engine Behind Nuxt and Analog

Nitro is the server engine that powers Nuxt 3, Analog, and Vinxi. Build server endpoints once, deploy anywhere — Vercel, Cloudflare, AWS Lambda, Deno, Bun, Node.js.

Why Nitro?

  • Universal deployment — one codebase, 15+ deployment targets
  • File-based API routesserver/api/users.ts/api/users
  • Auto-importsdefineEventHandler, readBody, etc.
  • Built-in caching — route caching, stale-while-revalidate

Quick Start

npx giget@latest nitro myserver
cd myserver
npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

API Routes

// server/api/hello.ts
export default defineEventHandler(() => {
  return { message: 'Hello, Nitro!' };
});

// server/api/users/index.get.ts
export default defineEventHandler(async () => {
  return await db.select().from(users);
});

// server/api/users/index.post.ts
export default defineEventHandler(async (event) => {
  const body = await readBody(event);
  return await db.insert(users).values(body).returning();
});

// server/api/users/[id].get.ts
export default defineEventHandler(async (event) => {
  const id = getRouterParam(event, 'id');
  return await db.select().from(users).where(eq(users.id, id));
});
Enter fullscreen mode Exit fullscreen mode

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/logger.ts
export default defineEventHandler((event) => {
  console.log(`${event.method} ${event.path}`);
});
Enter fullscreen mode Exit fullscreen mode

Caching

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

// Cache with key
export default defineCachedEventHandler(async (event) => {
  const id = getRouterParam(event, 'id');
  return await getUser(id);
}, {
  maxAge: 300,
  getKey: (event) => getRouterParam(event, 'id'),
});
Enter fullscreen mode Exit fullscreen mode

Storage (KV, FS, Redis, etc.)

// Use built-in KV storage
export default defineEventHandler(async () => {
  // Write
  await useStorage('data').setItem('key', { hello: 'world' });

  // Read
  const value = await useStorage('data').getItem('key');

  // List keys
  const keys = await useStorage('data').getKeys();

  return { value, keys };
});
Enter fullscreen mode Exit fullscreen mode

Deploy Anywhere

// nitro.config.ts
export default defineNitroConfig({
  // preset: 'node-server',      // Node.js
  // preset: 'vercel',           // Vercel
  // preset: 'cloudflare-pages', // Cloudflare
  // preset: 'deno-server',      // Deno
  // preset: 'bun',              // Bun
  // preset: 'aws-lambda',       // AWS Lambda
});
Enter fullscreen mode Exit fullscreen mode
npm run build
# Output in .output/ — ready for your platform
Enter fullscreen mode Exit fullscreen mode

Building APIs for data pipelines? Check out my Apify actors for web scraping, or email spinov001@gmail.com for custom server solutions.

Nitro, Express, or Hono — which server do you build on? Share below!

Top comments (0)