# fastify/fastify — codebase unpack

> Canonical page: https://codevetter.com/unpack/fastify

This is a deterministic Repo Unpack scan of fastify/fastify — a structural map, not a review, security audit, or maintainer-endorsed description.

- Scanned commit: 19d5be0daf1c0daace758efe3ea788f924ca1224 (2026-09-29)
- Last upstream commit: fix: resolve reply.mediaType from raw response headers (#7054)
- Generated by codevetter 1.15.0 on 2026-10-02
- 390 files scanned · 2.8 MB

Source inspection; upstream code and tests were not executed.

## Languages

- JavaScript: 263 files
- Markdown: 51 files
- TypeScript: 33 files
- YAML: 25 files
- JSON: 6 files
- Shell: 1 files

## Repository structure

- test/ — 232 files
- docs/ — 44 files
- lib/ — 31 files
- .github/ — 24 files
- examples/ — 19 files
- types/ — 15 files
- integration/ — 2 files
- scripts/ — 1 files

Probable source entrypoint: `lib/` (inferred from the tree, not upstream docs)

## Source layout — lib/

- lib/content-type-parser.js — 1 file
- lib/content-type.js — 1 file
- lib/decorate.js — 1 file
- lib/error-handler.js — 1 file
- lib/error-serializer.js — 1 file
- lib/error-status.js — 1 file
- lib/hooks.js — 1 file
- lib/initial-config-validation.js — 1 file
- lib/log-controller.js — 1 file
- lib/logger-factory.js — 1 file
- lib/noop-set.js — 1 file
- lib/plugin-override.js — 1 file
- lib/reply.js — 1 file
- lib/req-id-gen-factory.js — 1 file

## Package

- package.json: fastify v6.0.0-alpha.4 — 50 declared dependencies

## Structural health signals

Average score 7/10 across 96 files; 29 hotspots. These are deterministic review leads, not proof of a bug.

## Recent history

- 19d5be0daf1c (2026-09-29) fix: resolve reply.mediaType from raw response headers (#7054)
- d174a98e1a54 (2026-09-28) docs: list fastify-mariadb as a community plugin (#7062)
- bc25b7499ace (2026-09-27) fix: remove error when HTTP QUERY request has empty body (#6929)
- c3051e5b60c0 (2026-09-26) fix: omit absent compileSerializationSchema metadata instead of passing null (#7001)
- 2e3ebc5f984e (2026-09-26) perf: avoid resetting the level of request child loggers (#7056)

## Overview

Fastify is a Node.js HTTP framework for developers building API servers, packaged here as CommonJS with TypeScript declarations at version 6.0.0-alpha.4. Its core combines encapsulated plugins, route-specific request contexts, lifecycle hooks, compiled schema validation and serialization, and configurable HTTP transports. This brief examines the pinned commit 19d5be0daf1c0daace758efe3ea788f924ca1224 through public source inspection; it reports no executed tests or measured performance.

## System map

The runtime centers on a factory exported as a CommonJS package, with separate TypeScript declarations. Fastify assembles transport, routing, request/reply behavior, and plugin boot rather than supplying a fixed application. Mutable facilities are scoped through plugin inheritance and symbol-keyed state. Database integrations belong to application plugins, while repository workflows exercise packaging and compatibility.
- package.json declares fastify.js as main, commonjs as module type, fastify.d.ts as declarations, and version 6.0.0-alpha.4. — [package.json#L1-7](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/package.json#L1-L7)
- fastify() calls processOptions, buildRouting, build404, wrapRouting, createServer, and buildSchemaController to assemble an instance. — [fastify.js#L89-117](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L89-L117)
- The root owns symbol-keyed lifecycle state, child instances, hooks, parser configuration, and scoped Request/Reply constructors. — [fastify.js#L120-176](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L120-L176)
- Avvio is configured with autostart false and use exposed as register; Fastify installs its encapsulation override and replaces ready. — [fastify.js#L359-380](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L359-L380)
- getServerInstance selects a custom serverFactory, HTTP/2 secure or plain server, or HTTP/1 HTTPS/HTTP server. — [lib/server.js#L308-347](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/server.js#L308-L347)
- Default schema compiler factories are loaded from @fastify/ajv-compiler and @fastify/fast-json-stringify-compiler. — [lib/schema-controller.js#L16-35](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/schema-controller.js#L16-L35) [package.json#L205-220](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/package.json#L205-L220)
- The database guide explicitly describes Fastify as database agnostic and demonstrates separately registered database plugins. — [docs/Guides/Database.md#L5-16](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/docs/Guides/Database.md#L5-L16) [docs/Guides/Database.md#L24-38](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/docs/Guides/Database.md#L24-L38)
- Repository commands separate lint, borp unit tests, TSTyche type tests, generated-code integrity, and prepublication checks. — [package.json#L13-30](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/package.json#L13-L30)

## Feature catalog

The user-facing product is a programmable server API. Developers declare routes, scope plugins, extend objects, configure parsers and schemas, and control transport and lifecycle behavior. Reply APIs support ordinary payloads as well as streams and Web API objects. Database and authentication examples show integrations supplied through plugins.
- Route shorthand methods include GET, HEAD, TRACE, DELETE, PATCH, POST, PUT, OPTIONS, QUERY, and all supported methods. — [fastify.js#L179-209](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L179-L209)
- route, hasRoute, and findRoute expose general registration and route discovery. — [fastify.js#L210-221](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L210-L221)
- The instance exposes addHook, shared schema access, compiler setters, reply serializer selection, and schema error formatting. — [fastify.js#L227-237](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L227-L237)
- Content parser APIs allow adding, inspecting, removing, and resetting parsers, including access to default JSON and text parsers. — [fastify.js#L240-246](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L240-L246)
- decorate, decorateRequest, decorateReply, and corresponding inspection APIs extend instance and per-request objects. — [fastify.js#L266-274](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L266-L274)
- inject offers simulated HTTP requests, lazily loads light-my-request, and boots an unstarted instance before dispatch. — [fastify.js#L474-509](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L474-L509)
- Reply.send recognizes Node streams, Web streams, Response objects, typed-array buffers, and ordinary strings. — [lib/reply.js#L177-207](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/reply.js#L177-L207)
- handlerTimeout starts a request deadline that aborts request.signal and sends an error if no reply has been sent. — [lib/route.js#L531-554](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L531-L554) [docs/Reference/Lifecycle.md#L44-48](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/docs/Reference/Lifecycle.md#L44-L48)
- Custom not-found handlers, error handlers, child logger factories, and router constraint strategies are public instance features. — [fastify.js#L277-288](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L277-L288)

## Data flow

Route definitions become contexts whose hooks and compiled schemas are finalized during boot. Incoming transport objects become scoped Request and Reply objects before entering the hook and parsing pipeline. Validation can transform request parts, and handler results enter the reply serializer and output hooks. State is predominantly instance and route state; documented persistence crosses into separately registered database clients.
- Route options populate Context with a bound handler, schema, configuration, compiler overrides, body limit, and handler timeout. — [lib/route.js#L328-354](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L328-L354)
- router.on stores routeHandler and Context together; preReady subsequently binds inherited and route-local hooks. — [lib/route.js#L359-360](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L359-L360) [lib/route.js#L388-395](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L388-L395)
- routeHandler derives a request ID and logger, then creates context.Request and context.Reply from raw transport objects and router outputs. — [lib/route.js#L460-480](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L460-L480) [lib/route.js#L526-529](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L526-L529)
- runPreParsing initially stores request.raw as the payload stream and passes through a preParsing runner before handleRequest. — [lib/route.js#L651-665](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L651-L665)
- For body-bearing methods, handleRequest chooses a parser using Content-Type; invalid media types produce 415. — [lib/handle-request.js#L39-82](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/handle-request.js#L39-L82)
- rawBody accumulates buffers, enforces received and encoded byte limits, checks declared content length, and decodes or copies once before parser invocation. — [lib/content-type-parser.js#L268-286](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/content-type-parser.js#L268-L286) [lib/content-type-parser.js#L302-323](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/content-type-parser.js#L302-L323)
- Successful parsing assigns request.body and proceeds to handler; parsing failure marks the reply as an error and requests connection closure. — [lib/content-type-parser.js#L230-242](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/content-type-parser.js#L230-L242)
- validateParam passes parentData to Ajv-compatible validators and permits synchronous custom results to replace a request part through value. — [lib/validation.js#L286-326](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/validation.js#L286-L326)
- preSerializationHookEnd chooses reply-specific, instance-default, or schema-based serialization, then enters onSendHook. — [lib/reply.js#L534-555](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/reply.js#L534-L555)
- The documented Redis persistence path reads req.body.key/value, calls the plugin-provided redis.set, and replies from its completion callback. — [docs/Guides/Database.md#L81-98](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/docs/Guides/Database.md#L81-L98)

## Behavior traces

Three concrete core flows were followed through source: startup and listening, request handling and reply serialization, and shutdown. Injection provides another entry into the same handler after readiness. The database write example illustrates an application-owned persistence boundary rather than an implemented core store. These are source traces, not runtime observations.
- Startup begins fastify() → processOptions → buildRouting/build404 → wrapRouting → createServer → SchemaController construction. — [fastify.js#L89-117](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L89-L117)
- Plugin boot installs Avvio → override; override calls registerPlugin, then either reuses the parent or constructs an inherited child with copied scoped facilities. — [fastify.js#L367-379](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L367-L379) [lib/plugin-override.js#L28-50](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/plugin-override.js#L28-L50)
- Promise listening follows listen → listenPromise → ready → transport server.listen; success resolves a logged address. — [lib/server.js#L105-123](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/server.js#L105-L123) [lib/server.js#L267-304](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/server.js#L267-L304)
- For localhost, listening continues through multipleBindings → dns.lookup → additional server instances → onListenHookRunner. — [lib/server.js#L105-118](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/server.js#L105-L118) [lib/server.js#L150-189](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/server.js#L150-L189)
- Request handling follows routeHandler → Request/Reply creation → onRequestHookRunner → runPreParsing → handleRequest. — [lib/route.js#L526-529](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L526-L529) [lib/route.js#L567-576](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L567-L576) [lib/route.js#L651-665](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L651-L665)
- After parsing, handler → preValidationCallback → validateSchema → validationCompleted → preHandlerCallback → context.handler; results use wrapThenable or reply.send. — [lib/handle-request.js#L89-145](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/handle-request.js#L89-L145) [lib/handle-request.js#L171-209](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/handle-request.js#L171-L209)
- Object reply serialization follows preSerializationHook → preSerializationHookEnd → serializer selection → onSendHook → onSendEnd. — [lib/reply.js#L520-555](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/reply.js#L520-L555) [lib/reply.js#L561-580](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/reply.js#L561-L580)
- Error sending enters onErrorHook; handleError selects the current or next inherited error handler, invokes it, and falls back to serialized transport output. — [lib/reply.js#L156-169](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/reply.js#L156-L169) [lib/error-handler.js#L30-75](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/error-handler.js#L30-L75) [lib/error-handler.js#L85-121](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/error-handler.js#L85-L121)
- Shutdown marks closing, closes routes, runs preClose, handles configured forced socket closure and available HTTP/2 session cleanup, then calls server.close unless an unstarted custom serverFactory instance takes the nextTick completion branch. — [fastify.js#L383-428](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L383-L428)
- The documented persistence flow is register Redis plugin → POST /foo → redis.set(req.body.key, req.body.value) → completion reply; it is an example integration. — [docs/Guides/Database.md#L81-103](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/docs/Guides/Database.md#L81-L103)

## Testing signals

Tests and CI were inspected, not executed; no passing result is asserted. The inspected runtime tests use node:test, selected by borp, while type assertions use TSTyche. CI defines operating-system, runtime, packaging, coverage, and integration checks. Inspection is bounded and does not establish exhaustive coverage or application-plugin correctness.
- borp selects test/**/*.test.js and test/**/*.test.mjs; inspected injection tests import node:test. — [.borp.yaml#L1-3](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/.borp.yaml#L1-L3) [test/inject.test.js#L1-7](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/test/inject.test.js#L1-L7)
- npm test combines lint, unit, and type checks; test:ci omits lint and runs unit plus types. — [package.json#L22-28](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/package.json#L22-L28)
- Injection tests assert readiness waiting, JSON payload, status code, and content length. — [test/inject.test.js#L16-37](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/test/inject.test.js#L16-L37)
- Prototype-poisoning tests use real listen/fetch requests and assert rejection, removal, and ignore-policy behavior. — [test/proto-poisoning.test.js#L6-26](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/test/proto-poisoning.test.js#L6-L26) [test/proto-poisoning.test.js#L29-74](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/test/proto-poisoning.test.js#L29-L74)
- Handler-timeout tests cover option validation, lazy AbortSignal creation, and client-disconnect abortion using a TCP connection. — [test/handler-timeout.test.js#L23-57](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/test/handler-timeout.test.js#L23-L57) [test/handler-timeout.test.js#L60-90](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/test/handler-timeout.test.js#L60-L90)
- TSTyche provider tests assert unknown defaults, provider remapping, explicit overrides, and TypeBox-derived typing. — [test/types/type-provider.tst.ts#L18-47](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/test/types/type-provider.tst.ts#L18-L47) [test/types/type-provider.tst.ts#L54-97](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/test/types/type-provider.tst.ts#L54-L97)
- Primary unit CI defines Node 24/26 across macOS, Ubuntu, and Windows, after quality and both coverage jobs. — [.github/workflows/ci.yml#L54-87](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/.github/workflows/ci.yml#L54-L87)
- The coverage command requires 100 percent lines; this is a configured threshold rather than an observed coverage result. — [package.json#L15-16](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/package.json#L15-L16)
- Production-install integration CI starts integration/server.js and invokes a shell smoke test covering GET, POST, PUT, and DELETE responses. — [.github/workflows/integration.yml#L48-59](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/.github/workflows/integration.yml#L48-L59) [integration/test.sh#L5-20](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/integration/test.sh#L5-L20)
- esbuild and webpack fixtures define bundle-and-test scripts; alternative-runtime packaging CI invokes both. — [test/bundler/esbuild/package.json#L3-8](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/test/bundler/esbuild/package.json#L3-L8) [test/bundler/webpack/package.json#L3-9](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/test/bundler/webpack/package.json#L3-L9) [.github/workflows/ci-alternative-runtime.yml#L97-111](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/.github/workflows/ci-alternative-runtime.yml#L97-L111)
- CITGM tests selected external plugins by linking this Fastify checkout into each plugin's own test environment; several database entries are commented out. — [.github/workflows/citgm.yml#L69-81](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/.github/workflows/citgm.yml#L69-L81) [.github/workflows/citgm-package.yml#L94-105](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/.github/workflows/citgm-package.yml#L94-L105)

## Risk map

The principal trust boundaries are request bytes, forwarding headers, application-supplied schemas, and plugin code. The source includes explicit defenses and warnings at several of these boundaries. Shutdown and hijacked responses require coordinated resource cleanup across modules. These are source observations and labeled hypotheses, not confirmed vulnerabilities; no whole-repository absence or exploitability is claimed.
- Schemas are a code-execution trust boundary: documentation warns that validation and serialization use new Function and must not accept user-provided schemas. — [docs/Reference/Validation-and-Serialization.md#L18-22](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/docs/Reference/Validation-and-Serialization.md#L18-L22)
- The guide warns against database access during initial async validation because of denial-of-service exposure, recommending preHandler instead. — [docs/Reference/Validation-and-Serialization.md#L24-28](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/docs/Reference/Validation-and-Serialization.md#L24-L28)
- External header-schema references retain original case and cannot safely be globally normalized; compilation detects them and emits FSTSEC002. — [lib/validation.js#L189-198](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/validation.js#L189-L198) [lib/validation.js#L242-249](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/validation.js#L242-L249)
- Async validator data is treated as pass/fail rather than unwrapped as error/value, explicitly preventing payload fields from replacing request parts or injecting validation errors. — [lib/validation.js#L309-317](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/validation.js#L309-L317)
- Body buffering checks both decoded received length and reported encoded length, with separate declared Content-Length verification. — [lib/content-type-parser.js#L268-283](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/content-type-parser.js#L268-L283) [lib/content-type-parser.js#L302-305](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/content-type-parser.js#L302-L305)
- JSON parsing delegates prototype and constructor handling to secure-json-parse; tests demonstrate that the ignore option permits observable prototype effects through Object.assign. — [lib/content-type-parser.js#L327-341](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/content-type-parser.js#L327-L341) [test/proto-poisoning.test.js#L53-74](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/test/proto-poisoning.test.js#L53-L74)
- Forwarded host and protocol are consumed only when proxyFn trusts the direct socket peer, making trustProxy policy security-sensitive. — [lib/request.js#L122-145](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/request.js#L122-L145)
- Default error serialization includes error.message, and failed serialization constructs a fallback using both serializer and original error messages. — [lib/error-handler.js#L91-112](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/error-handler.js#L91-L112)
- Hypothesis: timeout and hijack changes have broad cleanup risk because routeHandler stores AbortController/timer/socket metadata and Reply.hijack removes associated listeners and metadata. (inferred) — [lib/route.js#L531-564](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L531-L564) [lib/reply.js#L134-152](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/reply.js#L134-L152)
- Alternative-runtime unit CI uses continue-on-error, so its configured failures do not provide the same gating signal as an ordinary mandatory job. — [.github/workflows/ci-alternative-runtime.yml#L25-38](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/.github/workflows/ci-alternative-runtime.yml#L25-L38)
- Package-manager CI downloads and pipes a Yarn installer into bash; CITGM derives plugin checkout coordinates from npm registry metadata and runs external package tests. — [.github/workflows/package-manager-ci.yml#L70-79](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/.github/workflows/package-manager-ci.yml#L70-L79) [.github/workflows/citgm-package.yml#L77-105](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/.github/workflows/citgm-package.yml#L77-L105)

## Extension points

Plugins and encapsulation are the main composition mechanism. Public hooks, decorators, parsers, schema compilers, and constraint strategies offer narrower extension seams. Transport and error handling can also be replaced. These facilities have lifecycle and inheritance rules that extensions must preserve.
- register is Avvio's exposed use API, and override implements Fastify-specific plugin encapsulation. — [fastify.js#L367-376](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L367-L376) [lib/plugin-override.js#L28-38](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/plugin-override.js#L28-L38)
- Plugin metadata is read from Symbol.for('plugin-meta'), while Symbol.for('skip-override') requests parent-scope reuse. — [lib/plugin-utils.js#L19-21](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/plugin-utils.js#L19-L21) [lib/plugin-utils.js#L61-63](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/plugin-utils.js#L61-L63) [lib/plugin-override.js#L29-35](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/plugin-override.js#L29-L35)
- registerPlugin validates async handler shape, Fastify version, required decorators, and declared plugin dependencies. — [lib/plugin-utils.js#L147-153](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/plugin-utils.js#L147-L153)
- onRegister hooks receive each new child instance and options after scope construction. — [lib/plugin-override.js#L63-73](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/plugin-override.js#L63-L73)
- onRoute hooks can inspect or alter route options before Context construction; lifecycle hooks combine instance and route handlers at preReady. — [lib/route.js#L292-297](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L292-L297) [lib/route.js#L389-395](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L389-L395)
- schemaController accepts a bucket factory and compiler factories; child controllers seed their schema bucket from parent schemas. — [lib/schema-controller.js#L30-35](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/schema-controller.js#L30-L35) [lib/schema-controller.js#L40-58](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/schema-controller.js#L40-L58)
- setValidatorCompiler and setSerializerCompiler clone compiler-factory configuration and adapt a supplied compiler into a reusable builder. — [lib/schema-controller.js#L75-95](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/schema-controller.js#L75-L95) [lib/schema-controller.js#L97-116](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/schema-controller.js#L97-L116)
- addContentTypeParser supports multiple content types and inherits the instance body limit; registration is rejected after startup. — [lib/content-type-parser.js#L365-384](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/content-type-parser.js#L365-L384)
- serverFactory receives the HTTP handler and options and returns a user-supplied transport server. — [lib/server.js#L308-312](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/server.js#L308-L312)
- Constraint strategies, child logger factories, decorators, and error handlers are exposed through instance methods. — [fastify.js#L266-288](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L266-L288)

## Contributor handoff

Start from package wiring, factory assembly, and lifecycle documentation, then trace the exact changed behavior into its modules. Preserve plugin scope boundaries and boot-time context finalization. Tests and CI were inspected, not executed; their existence is not a passing result. The inventory is bounded, and generated-code checks or runtime verification require authorization beyond this read-only investigation.
- Read package.json and fastify.js first to establish package entry, declaration entry, scripts, and runtime assembly. — [package.json#L1-30](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/package.json#L1-L30) [fastify.js#L89-117](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/fastify.js#L89-L117)
- Use Lifecycle and Encapsulation references alongside implementation to understand hook ordering and parent/child visibility. — [docs/Reference/Lifecycle.md#L12-42](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/docs/Reference/Lifecycle.md#L12-L42) [docs/Reference/Encapsulation.md#L22-32](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/docs/Reference/Encapsulation.md#L22-L32)
- Changes to scoped mutable facilities must account for plugin-override's copying of Request, Reply, parsers, hooks, prefixes, and schema controllers. — [lib/plugin-override.js#L38-52](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/plugin-override.js#L38-L52)
- Route contexts are finalized during preReady, including hook binding, constructor optimization, 404 association, and schema compilation. — [lib/route.js#L389-439](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L389-L439)
- Preserve explicit undefined checks for boolean JSON schemas; false schemas must still trigger compiler setup. — [lib/route.js#L413-421](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/route.js#L413-L421) [lib/validation.js#L228-240](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/lib/validation.js#L228-L240)
- Follow neostandard with TypeScript enabled, no trailing commas, and the configured 120-character rule exceptions. — [eslint.config.js#L4-25](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/eslint.config.js#L4-L25)
- Generated config-validator and error-serializer are excluded from lint; integrity verification rebuilds them and compares Git diffs. — [eslint.config.js#L6-9](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/eslint.config.js#L6-L9) [package.json#L13-25](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/package.json#L13-L25)
- When execution is authorized, existing broad verification entrypoints are npm run unit, npm run test:types, npm run lint, and npm run test:ci; none was executed for this brief. — [package.json#L17-28](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/package.json#L17-L28)
- Type-provider behavior has separate declaration assertions, so runtime success alone would not validate provider inference. — [test/types/type-provider.tst.ts#L27-47](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/test/types/type-provider.tst.ts#L27-L47) [package.json#L26-28](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/package.json#L26-L28)
- Do not infer database integration correctness from the core smoke fixture: its inspected handlers return static or path-derived responses, while database operations appear in plugin examples. — [integration/server.js#L12-28](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/integration/server.js#L12-L28) [docs/Guides/Database.md#L81-98](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/docs/Guides/Database.md#L81-L98)
- Treat CI matrices and coverage thresholds as inspected configuration, not execution evidence; broader compatibility includes external workflow implementations outside this repository. — [.github/workflows/ci.yml#L31-38](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/.github/workflows/ci.yml#L31-L38) [.github/workflows/ci.yml#L54-87](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/.github/workflows/ci.yml#L54-L87) [package.json#L15-16](https://github.com/fastify/fastify/blob/19d5be0daf1c0daace758efe3ea788f924ca1224/package.json#L15-L16)

Source repository: https://github.com/fastify/fastify
Full evidence corpus: https://github.com/Codevetter/codevetter/tree/main/benchmarks/repo-unpacks/fastify.json

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
