Fastify is a high-performance web framework for Node.js designed to provide the best developer experience with the least overhead and a powerful plugin architecture. It offers efficient server handling with lower infrastructure costs, better responsiveness under load, and enhanced user satisfaction. The framework is focused on speed and efficiency, featuring JSON schema-based validation, built-in logging with Pino, comprehensive TypeScript support, and an extensive ecosystem of plugins.
npm install fastifyconst fastify = require('fastify')({ logger: true });For ES modules:
import Fastify from 'fastify';
const fastify = Fastify({ logger: true });TypeScript:
import fastify, { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
const server: FastifyInstance = fastify({ logger: true });const fastify = require('fastify')({ logger: true });
// Declare a route
fastify.get('/', async (request, reply) => {
return { hello: 'world' };
});
// Run the server
const start = async () => {
try {
await fastify.listen({ port: 3000 });
console.log('Server listening on http://localhost:3000');
} catch (err) {
fastify.log.error(err);
process.exit(1);
}
};
start();Fastify is built around several key architectural components:
Core server functionality including instance creation, server startup, shutdown, and configuration management.
function fastify(options?: FastifyServerOptions): FastifyInstance;interface FastifyInstance {
listen(opts?: FastifyListenOptions): Promise<string>;
listen(opts: FastifyListenOptions, callback: (err: Error | null, address: string) => void): void;
close(): Promise<undefined>;
ready(): FastifyInstance & Promise<undefined>;
addresses(): AddressInfo[];
}Route registration and handling for all HTTP methods with support for route options, constraints, and dynamic routing.
interface FastifyInstance {
get(url: string, options?: RouteShorthandOptions, handler?: RouteHandlerMethod): FastifyInstance;
post(url: string, options?: RouteShorthandOptions, handler?: RouteHandlerMethod): FastifyInstance;
put(url: string, options?: RouteShorthandOptions, handler?: RouteHandlerMethod): FastifyInstance;
delete(url: string, options?: RouteShorthandOptions, handler?: RouteHandlerMethod): FastifyInstance;
patch(url: string, options?: RouteShorthandOptions, handler?: RouteHandlerMethod): FastifyInstance;
head(url: string, options?: RouteShorthandOptions, handler?: RouteHandlerMethod): FastifyInstance;
options(url: string, options?: RouteShorthandOptions, handler?: RouteHandlerMethod): FastifyInstance;
all(url: string, options?: RouteShorthandOptions, handler?: RouteHandlerMethod): FastifyInstance;
route(options: RouteOptions): FastifyInstance;
hasRoute(options: { method: string; url: string; constraints?: object }): boolean;
findRoute(options: { method: string; url: string; constraints?: object }): object | null;
addHttpMethod(method: string, options?: { hasBody?: boolean }): FastifyInstance;
supportedMethods: string[];
}Fastify's powerful plugin architecture for extending functionality with encapsulation and dependency management.
interface FastifyInstance {
register(plugin: FastifyPlugin, options?: FastifyPluginOptions): FastifyInstance;
after(): FastifyInstance & Promise<undefined>;
hasPlugin(name: string): boolean;
printPlugins(): string;
withTypeProvider(): FastifyInstance;
}Lifecycle hooks for intercepting and modifying request/response processing at various stages.
interface FastifyInstance {
addHook(hookName: string, handler: Function): FastifyInstance;
}
type HookNames = 'onRequest' | 'preParsing' | 'preValidation' | 'preHandler' |
'preSerialization' | 'onSend' | 'onResponse' | 'onTimeout' |
'onError' | 'onClose' | 'onReady' | 'onListen' | 'onRegister' |
'onRequestAbort' | 'preClose';JSON Schema integration for request validation, response serialization, and documentation generation.
interface FastifyInstance {
addSchema(schema: unknown): FastifyInstance;
getSchema(schemaId: string): unknown;
getSchemas(): Record<string, unknown>;
setValidatorCompiler(compiler: FastifySchemaCompiler): FastifyInstance;
setSerializerCompiler(compiler: FastifySerializerCompiler): FastifyInstance;
setSchemaController(options: FastifySchemaControllerOptions): FastifyInstance;
setSchemaErrorFormatter(formatter: SchemaErrorFormatter): FastifyInstance;
setReplySerializer(serializer: (payload: any) => string): FastifyInstance;
validatorCompiler: FastifySchemaCompiler;
serializerCompiler: FastifySerializerCompiler;
}Comprehensive error handling system with custom error handlers and built-in error types.
interface FastifyInstance {
setErrorHandler(handler: (error: FastifyError, request: FastifyRequest, reply: FastifyReply) => void): FastifyInstance;
setNotFoundHandler(handler: (request: FastifyRequest, reply: FastifyReply) => void): FastifyInstance;
setNotFoundHandler(options: object, handler: (request: FastifyRequest, reply: FastifyReply) => void): FastifyInstance;
}Customizable content type parsing system for handling different request body formats.
interface FastifyInstance {
addContentTypeParser(contentType: string, options: object, parser: Function): FastifyInstance;
hasContentTypeParser(contentType: string): boolean;
removeContentTypeParser(contentType: string): FastifyInstance;
removeAllContentTypeParsers(): FastifyInstance;
getDefaultJsonParser(): Function;
}Extend Fastify instances, requests, and replies with custom properties and methods.
interface FastifyInstance {
decorate(name: string, value: any, dependencies?: string[]): FastifyInstance;
decorateRequest(name: string, value: any, dependencies?: string[]): FastifyInstance;
decorateReply(name: string, value: any, dependencies?: string[]): FastifyInstance;
hasDecorator(name: string): boolean;
hasRequestDecorator(name: string): boolean;
hasReplyDecorator(name: string): boolean;
getDecorator(name: string): any;
}Built-in testing support with HTTP injection capabilities for unit and integration testing.
interface FastifyInstance {
inject(options: InjectOptions): Promise<LightMyRequestResponse>;
inject(options: InjectOptions, callback: (err: Error, response: LightMyRequestResponse) => void): void;
inject(): LightMyRequestChain;
}Manage routing constraint strategies for advanced route matching.
interface FastifyInstance {
addConstraintStrategy(strategy: ConstraintStrategy): FastifyInstance;
hasConstraintStrategy(name: string): boolean;
}Configure request ID generation and child logger factory.
interface FastifyInstance {
setGenReqId(fn: (request: any) => string): FastifyInstance;
setChildLoggerFactory(factory: FastifyChildLoggerFactory): FastifyInstance;
genReqId: (request: any) => string;
childLoggerFactory: FastifyChildLoggerFactory;
}Utilities for route introspection and debugging.
interface FastifyInstance {
printRoutes(options?: PrintRoutesOptions): string;
}
interface PrintRoutesOptions {
includeMeta?: string[];
includeHooks?: boolean;
commonPrefix?: boolean;
}interface FastifyServerOptions {
ignoreTrailingSlash?: boolean;
ignoreDuplicateSlashes?: boolean;
connectionTimeout?: number;
keepAliveTimeout?: number;
maxRequestsPerSocket?: number;
forceCloseConnections?: boolean | 'idle';
requestTimeout?: number;
pluginTimeout?: number;
bodyLimit?: number;
maxParamLength?: number;
disableRequestLogging?: boolean;
logger?: boolean | FastifyLoggerOptions;
trustProxy?: boolean | string | string[] | number | Function;
querystringParser?: (str: string) => object;
caseSensitive?: boolean;
allowUnsafeRegex?: boolean;
schemaController?: FastifySchemaControllerOptions;
ajv?: AjvOptions;
serializerOpts?: object;
http2?: boolean;
https?: object;
serverFactory?: Function;
genReqId?: Function;
requestIdHeader?: string | false;
useSemicolonDelimiter?: boolean;
return503OnClosing?: boolean;
exposeHeadRoutes?: boolean;
onProtoPoisoning?: 'error' | 'remove' | 'ignore';
onConstructorPoisoning?: 'error' | 'remove' | 'ignore';
frameworkErrors?: Function;
rewriteUrl?: Function;
schemaErrorFormatter?: Function;
clientErrorHandler?: Function;
childLoggerFactory?: Function;
}interface FastifyRequest<RouteGeneric = RouteGenericInterface> {
id: string;
params: RouteGeneric['Params'];
raw: RawRequestDefaultExpression;
query: RouteGeneric['Querystring'];
body: RouteGeneric['Body'];
headers: RouteGeneric['Headers'];
log: FastifyLoggerInstance;
server: FastifyInstance;
ip: string;
ips?: string[];
hostname: string;
port?: number;
url: string;
originalUrl?: string;
protocol: string;
method: string;
routerPath: string;
routerMethod: string;
routeOptions: RouteOptions;
is404: boolean;
socket: Socket;
validationError?: FastifySchemaValidationError;
getValidationFunction(httpPart?: string): Function;
compileValidationSchema(schema: object, httpPart?: string): Function;
validateInput(input: any, schema?: object, httpPart?: string): boolean;
}
interface FastifyReply<RouteGeneric = RouteGenericInterface> {
raw: RawReplyDefaultExpression;
log: FastifyLoggerInstance;
request: FastifyRequest<RouteGeneric>;
server: FastifyInstance;
statusCode: number;
sent: boolean;
elapsedTime: number;
routeOptions: RouteOptions;
code(statusCode: number): FastifyReply;
status(statusCode: number): FastifyReply;
header(name: string, value: any): FastifyReply;
headers(headers: object): FastifyReply;
getHeader(name: string): string | string[] | undefined;
getHeaders(): object;
hasHeader(name: string): boolean;
removeHeader(name: string): FastifyReply;
trailer(key: string, fn: Function): FastifyReply;
hasTrailer(key: string): boolean;
removeTrailer(key: string): FastifyReply;
type(contentType: string): FastifyReply;
cookie(name: string, value: any, options?: object): FastifyReply;
clearCookie(name: string, options?: object): FastifyReply;
redirect(url: string): FastifyReply;
redirect(code: number, url: string): FastifyReply;
send(payload?: any): FastifyReply;
serializer(fn: Function): FastifyReply;
serialize(payload: any): string;
hijack(): FastifyReply;
callNotFound(): void;
writeEarlyHints(hints: object, callback?: Function): void;
getSerializationFunction(schema: object): Function;
compileSerializationSchema(schema: object, httpStatus?: number, contentType?: string): Function;
serializeInput(input: any, schema: object, httpStatus?: number, contentType?: string): string;
}
interface RouteGenericInterface {
Body?: unknown;
Querystring?: unknown;
Params?: unknown;
Headers?: unknown;
Reply?: unknown;
}
interface RouteShorthandOptions {
schema?: FastifySchema;
attachValidation?: boolean;
onRequest?: Function | Function[];
preParsing?: Function | Function[];
preValidation?: Function | Function[];
preHandler?: Function | Function[];
preSerialization?: Function | Function[];
onSend?: Function | Function[];
onResponse?: Function | Function[];
onTimeout?: Function | Function[];
onError?: Function | Function[];
config?: object;
version?: string;
constraints?: object;
errorHandler?: Function;
childLoggerFactory?: Function;
}
interface RouteOptions extends RouteShorthandOptions {
method: string | string[];
url: string;
handler: Function;
}
interface FastifySchemaValidationError {
instancePath: string;
schemaPath: string;
keyword: string;
params: object;
message?: string;
data?: any;
}
interface ConstraintStrategy {
name: string;
storage(): object;
deriveConstraint(req: any): any;
validate(value: any): boolean;
mustMatchWhenDerived?: boolean;
}Fastify exports all built-in error codes for error handling and testing.
const { errorCodes } = require('fastify');
// or
import fastify, { errorCodes } from 'fastify';
interface FastifyErrorCodes {
FST_ERR_VALIDATION: string;
FST_ERR_INVALID_URL: string;
FST_ERR_ROUTE_ALREADY_EXISTS: string;
FST_ERR_PLUGIN_NOT_VALID: string;
FST_ERR_HOOK_INVALID_TYPE: string;
FST_ERR_HOOK_INVALID_HANDLER: string;
FST_ERR_INSTANCE_ALREADY_LISTENING: string;
// ... and many more error codes
}