Node.js Patterns
Fastify (preferred over Express for new services)
import Fastify from 'fastify'
const app = Fastify({ logger: true })
// Plugin — encapsulated scope
app.register(async (instance) => {
instance.get('/users', async (request, reply) => {
const users = await db.user.findMany()
return users // Fastify auto-serializes
})
instance.post('/users', {
schema: {
body: {
type: 'object',
required: ['email', 'name'],
properties: {
email: { type: 'string', format: 'email' },
name: { type: 'string', minLength: 1 },
},
},
},
handler: async (request, reply) => {
const user = await db.user.create({ data: request.body as any })
reply.code(201)
return user
},
})
}, { prefix: '/api/v1' })
await app.listen({ port: 3000, host: '0.0.0.0' })
Express with TypeScript
import express, { Request, Response, NextFunction } from 'express'
const app = express()
app.use(express.json())
// Typed request handler
interface CreateUserBody { email: string; name: string }
app.post('/users', async (
req: Request<{}, {}, CreateUserBody>,
res: Response,
next: NextFunction
) => {
try {
const user = await db.user.create({ data: req.body })
res.status(201).json(user)
} catch (err) {
next(err)
}
})
// Error middleware (4 args — must match signature)
app.use((err: Error, req: Request, res: Response, _next: NextFunction) => {
console.error(err)
res.status(500).json({ error: err.message })
})
Streams
import { pipeline } from 'node:stream/promises'
import { createReadStream, createWriteStream } from 'node:fs'
import { createGzip } from 'node:zlib'
// Safe pipeline (auto-cleans up on error)
await pipeline(
createReadStream('input.log'),
createGzip(),
createWriteStream('input.log.gz')
)
// Transform stream
import { Transform } from 'node:stream'
const upper = new Transform({
transform(chunk, _enc, callback) {
callback(null, chunk.toString().toUpperCase())
},
})
EventEmitter
import { EventEmitter } from 'node:events'
interface Events {
data: (payload: { id: string }) => void
error: (err: Error) => void
drain: () => void
}
class Queue extends EventEmitter {
declare emit: <K extends keyof Events>(event: K, ...args: Parameters<Events[K]>) => boolean
declare on: <K extends keyof Events>(event: K, listener: Events[K]) => this
push(item: { id: string }) {
this.emit('data', item)
}
}
Worker Threads
import { Worker, isMainThread, parentPort, workerData } from 'node:worker_threads'
if (isMainThread) {
const worker = new Worker(__filename, { workerData: { input: [1, 2, 3] } })
worker.on('message', (result) => console.log('Result:', result))
worker.on('error', console.error)
} else {
const result = (workerData.input as number[]).map(x => x * 2)
parentPort!.postMessage(result)
}
Cluster for CPU-bound scaling
import cluster from 'node:cluster'
import os from 'node:os'
if (cluster.isPrimary) {
const cpus = os.availableParallelism()
for (let i = 0; i < cpus; i++) cluster.fork()
cluster.on('exit', (worker) => {
console.warn(`Worker ${worker.process.pid} died, restarting`)
cluster.fork()
})
} else {
// Start your HTTP server here — each worker listens on the same port
startServer()
}
Graceful Shutdown
async function shutdown(signal: string) {
console.log(`Received ${signal}, shutting down...`)
server.close(async () => {
await db.$disconnect()
process.exit(0)
})
// Force exit after 10s
setTimeout(() => process.exit(1), 10_000).unref()
}
process.on('SIGTERM', () => shutdown('SIGTERM'))
process.on('SIGINT', () => shutdown('SIGINT'))
Environment Config
import { z } from 'zod'
const envSchema = z.object({
NODE_ENV: z.enum(['development', 'test', 'production']),
PORT: z.coerce.number().default(3000),
DATABASE_URL: z.string().url(),
JWT_SECRET: z.string().min(32),
})
export const env = envSchema.parse(process.env)
// Crashes at startup with a clear error if required vars are missing
HTTP Client (native fetch / undici)
// Node 18+: global fetch is available
const res = await fetch('https://api.example.com/data', {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
body: JSON.stringify(payload),
signal: AbortSignal.timeout(5000),
})
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`)
const data = await res.json()
File System (async)
import { readFile, writeFile, mkdir, rm } from 'node:fs/promises'
import { join } from 'node:path'
const content = await readFile(join(__dirname, 'data.json'), 'utf8')
const parsed = JSON.parse(content)
await writeFile('output.json', JSON.stringify(parsed, null, 2))
await mkdir('uploads', { recursive: true })
await rm('tmp', { recursive: true, force: true })