Fastify Best Practices
A condensed summary of the 25 most important Fastify practices for Node.js teams - drawn from every page in this section.
Search across all documentation pages
A condensed summary of the 25 most important Fastify practices for Node.js teams - drawn from every page in this section.
Schema every public endpoint: Body, params, query, and response - JSON Schema Validation.
Set additionalProperties: false on objects: Reject unexpected input early.
Use response schemas for serialization speed: Compiled serializers beat JSON.stringify.
One plugin per domain: users, orders, billing as separate plugins - Fastify Plugins.
Wrap shared plugins with fastify-plugin: DB, auth, and config must be globally visible.
Load plugins before routes: Autoload plugins/ dir before routes/ dir.
Use @fastify/autoload for conventions: Predictable file-based registration.
App factory for tests: buildApp() exported from app.ts - Testing Fastify Apps.
Test with inject(), not supertest: Faster, no port conflicts.
Call app.close() in test teardown: Prevent open handle warnings.
Pino JSON to stdout in production: No pino-pretty in prod - Logging with Pino.
Redact sensitive fields: authorization, password, cookie in log config.
Propagate request ID: genReqId from x-request-id header.
Centralized setErrorHandler: Consistent error JSON shape.
Attach statusCode to operational errors: 404, 422, 401 as thrown errors.
Tune server timeouts after listen: keepAliveTimeout, headersTimeout on app.server.
Clean up in onClose hooks: Close DB pools and Redis connections on SIGTERM.
Use TypeBox or Zod type provider: Keep schemas and TypeScript types in sync.
Generate OpenAPI from schemas: @fastify/swagger for contract documentation.
Disable logger in tests: { logger: false } in test app factory.
Avoid Express middleware in Fastify: Use native plugins for encapsulation.
Profile before claiming Fastify speed wins: Database is usually the bottleneck - Fastify vs Express ADR.
Version plugin APIs with semver: Breaking decorator changes affect all consumers.
Use await app.listen() (Fastify 5): Async listen is the current API.
Document framework choice in ADR: Revisit annually or at 10x load change.
Schema every public route. Validation prevents bad input; response schemas accelerate serialization.
Fastify if schema validation and throughput matter. Express if team familiarity is the priority. See the ADR page.
apps/api/src/{plugins,routes,schemas}/. Share schemas package across services if needed.
NestJS when you need DI, guards, and modular architecture at scale. Raw Fastify for focused APIs.
Rewrite as a dedicated sprint, not incremental. Thin Express handlers make porting easier.
Stack versions: This page was written for Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, and NestJS 11.
Reviewed by Chris St. John·Last updated Jul 16, 2026