DEV Community

Alex Spinov
Alex Spinov

Posted on

Nitro Has a Free API You Should Know About

Nitro is the server engine behind Nuxt, but it works standalone too. It's a universal JavaScript server that deploys anywhere — Node.js, Deno, Bun, Cloudflare Workers, AWS Lambda, and more.

Quick Start

npx giget nitro my-app
cd my-app && npm install && npm run dev
Enter fullscreen mode Exit fullscreen mode

API Routes

Create routes by adding files to routes/:

// routes/api/users.get.ts
export default defineEventHandler(async (event) => {
  const query = getQuery(event)
  return db.user.findMany({ take: Number(query.limit) || 10 })
})

// routes/api/users.post.ts
export default defineEventHandler(async (event) => {
  const body = await readBody(event)
  return db.user.create({ data: body })
})

// routes/api/users/[id].get.ts
export default defineEventHandler(async (event) => {
  const id = getRouterParam(event, "id")
  const user = await db.user.findUnique({ where: { id } })
  if (!user) throw createError({ statusCode: 404 })
  return user
})

// routes/api/users/[id].patch.ts
export default defineEventHandler(async (event) => {
  const id = getRouterParam(event, "id")
  const body = await readBody(event)
  return db.user.update({ where: { id }, data: body })
})
Enter fullscreen mode Exit fullscreen mode

Built-in Caching

// routes/api/stats.get.ts
export default defineCachedEventHandler(async () => {
  const stats = await computeExpensiveStats()
  return stats
}, {
  maxAge: 60 * 60,   // 1 hour
  swr: true,          // Stale-while-revalidate
  staleMaxAge: 3600   // Serve stale for 1h while revalidating
})

// Cached utility functions
const getConfig = defineCachedFunction(async (key: string) => {
  return db.config.findUnique({ where: { key } })
}, {
  maxAge: 300,
  getKey: (key) => `config:${key}`
})
Enter fullscreen mode Exit fullscreen mode

Middleware

// middleware/auth.ts
export default defineEventHandler(async (event) => {
  const token = getHeader(event, "authorization")?.replace("Bearer ", "")
  if (event.path.startsWith("/api/protected") && !token) {
    throw createError({ statusCode: 401, message: "Unauthorized" })
  }
  if (token) {
    event.context.user = await verifyToken(token)
  }
})

// middleware/cors.ts
export default defineEventHandler((event) => {
  setResponseHeaders(event, {
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Methods": "GET,POST,PUT,DELETE"
  })
})
Enter fullscreen mode Exit fullscreen mode

Storage API — Universal Key-Value

// nitro.config.ts
export default defineNitroConfig({
  storage: {
    redis: { driver: "redis", url: "redis://localhost:6379" },
    fs: { driver: "fs", base: "./data" },
    db: { driver: "cloudflare-kv-binding", binding: "MY_KV" }
  }
})

// routes/api/cache.ts
export default defineEventHandler(async (event) => {
  const storage = useStorage("redis")

  // 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 }
})
Enter fullscreen mode Exit fullscreen mode

WebSocket

// routes/_ws.ts
export default defineWebSocketHandler({
  open(peer) {
    peer.subscribe("broadcast")
    peer.send(JSON.stringify({ type: "connected", id: peer.id }))
  },
  message(peer, message) {
    const data = JSON.parse(message.text())
    peer.publish("broadcast", JSON.stringify({
      from: peer.id,
      ...data
    }))
  },
  close(peer) {
    peer.publish("broadcast", JSON.stringify({
      type: "disconnected", id: peer.id
    }))
  }
})
Enter fullscreen mode Exit fullscreen mode

Deploy Anywhere

# Node.js
npx nitropack build --preset node-server

# Cloudflare Workers
npx nitropack build --preset cloudflare-module

# Vercel
npx nitropack build --preset vercel-edge

# AWS Lambda
npx nitropack build --preset aws-lambda

# Deno Deploy
npx nitropack build --preset deno-deploy
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  • Universal — same code runs on Node, Deno, Bun, Edge, Lambda
  • File-based routing with HTTP method suffixes
  • Built-in caching with SWR support
  • Storage API for Redis, FS, KV with one interface
  • WebSocket support
  • Auto-imports for all utilities

Explore Nitro docs for the complete reference.


Building web scrapers or data pipelines? Check out my Apify actors for ready-made solutions, or email spinov001@gmail.com for custom development.

Top comments (0)