We use cookies to understand how the site is used and to display ads. Analytics and advertising only run after you accept. You can change your choice anytime. Privacy policy

Skip to content
devvkit
$devvkit learn --librarie fastify-guide

Fastify Guide

[nodejs][http][server][performance]
JavaScript / TypeScript
Install
npm install fastify

Fastify is built for speed. Its schema-based serialization (using JSON Schema) is significantly faster than Express's runtime JSON.stringify. Benchmarks show 2-3x throughput over Express.

The plugin system provides encapsulation: each plugin has its own scope. Decorators extend the core request/reply objects. Hooks (onRequest, preHandler, onSend) replace Express middleware chains.

Fastify 5 supports TypeScript natively. The logger (Pino) is the fastest Node.js logger. Validation via @fastify/type-provider-typebox integrates with TypeScript types.

Setup

Basic server· Create Fastify app.
import Fastify from 'fastify'

const app = Fastify({ logger: true })

app.get('/', async (req, reply) => {
  return { hello: 'world' }
})

app.listen({ port: 3000 })

Schemas & Validation

Route with schema· Define JSON Schema for validation.
app.get('/users/:id', {
  schema: {
    params: { type: 'object', properties: { id: { type: 'integer' } } },
    response: { 200: { type: 'object', properties: { id: { type: 'integer' }, name: { type: 'string' } } } },
  },
}, async (req) => {
  return db.findUser(req.params.id)
})
TypeBox integration· Type-safe schemas.
import { Type, TypeBoxTypeProvider } from '@fastify/type-provider-typebox'

const app = Fastify().withTypeProvider<TypeBoxTypeProvider>()

app.get('/users/:id', {
  schema: {
    params: Type.Object({ id: Type.Number() }),
    response: { 200: Type.Object({ id: Type.Number(), name: Type.String() }) },
  },
}, async (req) => db.findUser(req.params.id))

Plugins

Register plugin· Encapsulated plugin.
import fp from 'fastify-plugin'

export default fp(async function dbPlugin(app, opts) {
  app.decorate('db', {
    getUsers: () => fetch('/api/users').then(r => r.json()),
  })
})

// In app:
app.register(dbPlugin)
app.get('/users', async (req) => app.db.getUsers())

Hooks

Hook: auth· Pre-handler for auth.
app.addHook('preHandler', async (req, reply) => {
  const token = req.headers.authorization
  if (!token) return reply.status(401).send({ error: 'Unauthorized' })
  req.user = await verifyToken(token)
})
Content type parser· Custom body parsing.
app.addContentTypeParser('application/csv', { parseAs: 'string' }, (req, body, done) => {
  done(null, parseCSV(body as string))
})

Performance

Graceful shutdown· Clean server stop.
const signals = ['SIGINT', 'SIGTERM']
for (const signal of signals) {
  process.on(signal, async () => {
    await app.close()
    process.exit(0)
  })
}