DEV Community

Alex Spinov
Alex Spinov

Posted on

Nitro Has a Free API: The Universal Server Engine Behind Nuxt and More

Every framework builds its own server layer. Nitro built one server layer for all frameworks.

What Is Nitro?

Nitro is a universal web server engine from the UnJS ecosystem. It powers Nuxt, Analog, SolidStart, and works standalone. Write your server once, deploy anywhere — Node.js, Deno, Bun, Cloudflare Workers, Vercel, Netlify, AWS Lambda.

// routes/hello.ts
export default defineEventHandler(() => {
  return { message: "Hello from Nitro!" }
})
Enter fullscreen mode Exit fullscreen mode
npx nitropack init my-server
cd my-server
npm run dev
# API at http://localhost:3000/hello
Enter fullscreen mode Exit fullscreen mode

File-Based Routing

routes/
  index.ts           → GET /
  hello.ts           → GET /hello
  users/
    index.get.ts     → GET /users
    index.post.ts    → POST /users
    [id].get.ts      → GET /users/:id
    [id].put.ts      → PUT /users/:id
Enter fullscreen mode Exit fullscreen mode

Features

// Route parameters
// routes/users/[id].ts
export default defineEventHandler(async (event) => {
  const id = getRouterParam(event, 'id')
  const body = await readBody(event) // POST body
  const query = getQuery(event) // URL params
  return { id, body, query }
})

// Middleware
// middleware/auth.ts
export default defineEventHandler((event) => {
  const token = getHeader(event, 'authorization')
  if (!token) throw createError({ statusCode: 401 })
})

// Server storage (KV)
export default defineEventHandler(async () => {
  await useStorage().setItem('key', 'value')
  return await useStorage().getItem('key')
})

// Caching
export default defineCachedEventHandler(async () => {
  return await expensiveQuery()
}, { maxAge: 60 * 60 }) // 1 hour cache

// WebSockets
export default defineWebSocketHandler({
  open(peer) { peer.send("Connected!") },
  message(peer, message) { peer.send(\`Echo: \${message}\`) },
})

// Scheduled tasks
export default defineTask({
  meta: { description: "Cleanup old records" },
  run: async () => { await cleanup(); return { result: "done" } }
})
Enter fullscreen mode Exit fullscreen mode

Deploy Anywhere

# Build for any platform
NITRO_PRESET=cloudflare-pages npx nitro build
NITRO_PRESET=vercel npx nitro build
NITRO_PRESET=netlify npx nitro build
NITRO_PRESET=aws-lambda npx nitro build
NITRO_PRESET=deno-server npx nitro build
NITRO_PRESET=bun npx nitro build
NITRO_PRESET=node-server npx nitro build
Enter fullscreen mode Exit fullscreen mode

Same code, different preset, different platform. Zero code changes.

Why Nitro

  • Universal — one codebase, any deployment target
  • Auto-importsdefineEventHandler, getQuery, etc. — no imports needed
  • Hot reload — instant feedback during development
  • Tree-shaking — only ships code your routes actually use
  • Ecosystem — built on UnJS (ofetch, h3, unstorage, hookable)

Building server applications? Check out my developer tools or email spinov001@gmail.com.

Top comments (0)