fastify-plugin

Wraps a Fastify plugin function so it breaks out of encapsulation, checks the host's Fastify version, and carries dependency/name metadata.

Library
npm
v6.0.0
240stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
68/100Good
Development Activity60
Maintenance60
Community72
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
78/100Good
Architecture80
Code Quality90
Innovation55
Learning Curve85

fastify-plugin is the standard way to author well-behaved plugins for the Fastify web framework. Fastify normally scopes everything a plugin registers — decorators, hooks, routes — to that plugin’s own encapsulation context, so a decorator added inside a plugin isn’t visible to sibling plugins or the parent instance. fastify-plugin wraps a plugin function and sets the internal skip-override symbol, which tells Fastify to skip creating a new encapsulation context for it, making the plugin’s decorators and hooks visible at the level it was registered.

Beyond encapsulation, fastify-plugin standardizes how plugins declare their own requirements: a semver range for the minimum Fastify version they need, a name so Fastify’s dependency graph can identify them, and lists of decorators and dependencies that must already exist before the plugin loads. Fastify validates all of this at registration time and throws a clear error if a version or dependency check fails, instead of surfacing a confusing runtime bug. It is maintained by the Fastify core team and is a near-universal dependency of the Fastify plugin ecosystem.

What You Get

  • Encapsulation bypass - sets the skip-override symbol so a plugin’s decorators, hooks, and routes attach at the parent scope instead of being sandboxed
  • Fastify version guard - accepts a semver range via the fastify option (or a bare version string) and Fastify rejects registration if the host doesn’t satisfy it
  • Plugin naming - a name option that Fastify’s internal dependency graph uses to identify the plugin for other plugins’ dependencies checks
  • Dependency + decorator checks - dependencies and decorators options let a plugin assert that other named plugins or specific fastify/reply/request decorators are already registered
  • Optional re-encapsulation - an encapsulate: true option keeps the plugin’s own decorators private while still validating its name and dependencies
  • CommonJS and ESM interop - auto-attaches a .default property and a camelCase named property to the wrapped function so it works with require, import, and transpiled default exports

Common Use Cases

  • Publishing a reusable Fastify plugin - wrap the plugin’s entry function with fp() before publishing to npm so consumers’ decorators/hooks work at the expected scope
  • Sharing a decorator across route files - wrap an internal plugin that calls fastify.decorate() so the decorator is visible outside that plugin’s own file
  • Enforcing a minimum Fastify version - pass { fastify: '5.x' } so misconfigured apps get an explicit registration-time error instead of a confusing runtime failure
  • Composing plugins with explicit dependencies - declare dependencies: ['plugin-a'] so a plugin refuses to load out of order in a larger application’s plugin tree

Under The Hood

Architecture The entire package is a single wrapper function in index.js that takes a plugin function and an options object (or a bare version string, normalized into { fastify: options }). It validates the function and options shapes, derives an automatic plugin name via lib/getPluginName.js when none is supplied (parsing the function’s name or, for anonymous functions, extracting a filename from a captured stack trace), and stamps three well-known symbols onto the function: skip-override, fastify.display-name, and plugin-meta. Fastify’s own plugin-loading code (avvio, consumed at registration time, not part of this repo) reads those symbols to decide whether to create a new encapsulation context and to run version/dependency validation. A small lib/toCamelCase.js helper additionally exposes the plugin under a camelCase property matching its name, to support ergonomic named imports in TypeScript/ESM consumers. There is no internal layering beyond this — it is intentionally a thin, single-purpose annotation layer over a function. Tech Stack The runtime code has zero production dependencies and targets plain CommonJS Node.js, with a TypeScript declaration file (types/index.d.ts) hand-written against Fastify’s own plugin types (FastifyPluginCallback, FastifyPluginAsync) for typed consumers. Development tooling includes fastify itself and @fastify/type-provider-typebox as devDependencies for integration-style tests, neostandard/eslint for linting, c8 for coverage-enforced test running via Node’s built-in node:test runner, tstyche for type-level test assertions against the .d.ts file, and proxyquire for isolating the stack-trace-based name-extraction logic in tests. CI is delegated to a shared reusable workflow (fastify/workflows) rather than a bespoke pipeline. Code Quality Tests live under test/ and are extensive relative to the package’s small surface area, covering the callback and async plugin forms, error paths for non-function input and malformed options, the auto-naming fallback via stack-trace parsing, ESM/bundler interop, and composite/nested plugin scenarios. c8 --100 enforces full statement coverage on every run, and tstyche separately type-checks the declaration file against example .tst.ts fixtures, so both the runtime behavior and the public TypeScript types are continuously verified. Error handling is explicit — invalid inputs throw TypeError with descriptive messages rather than failing silently — and the codebase follows a consistent, lint-enforced style throughout. What Makes It Unique Rather than solving encapsulation with a configuration flag or a separate API, fastify-plugin’s approach is to attach behavior to the plugin function itself via symbols that Fastify’s core loader already understands, which keeps the mental model simple: any plugin function can opt out of encapsulation by passing through this one wrapper. Combining that with declarative version and dependency metadata — checked automatically at registration rather than left to documentation or runtime errors — is what makes it close to a de facto requirement for any plugin published into the Fastify ecosystem, despite being a tiny, dependency-free package.

Used by 8 apps in this directory

TypeScript
99%
Other

Activepieces

Automation · AI Assistants

24,298

Open-source AI automation platform that converts 280+ workflow integrations into MCP servers for LLMs, with no-code builders and TypeScript extensibility.

View details
92
Repo Health
85
Technical
64
Dependency
Built with
TypeScript99%
Updated today
TypeScript
92%
MIT

Dittofeed

Marketing · Automation

2,926

Open-source omni-channel customer engagement platform for automating transactional and marketing messages via email, SMS, WhatsApp, Slack, and mobile push.

View details
54
Repo Health
75
Technical
62
Dependency
Built with
TypeScript92%
Updated 5 months ago
TypeScript
99%
MIT

GraphQL Hive

Developer Tools · Devops · Monitoring

484

Open-source GraphQL schema registry and observability platform with breaking change detection, federation support, and CI/CD integration for teams of any size.

View details
89
Repo Health
81
Technical
69
Dependency
Built with
TypeScript99%
Updated 2 days ago
TypeScript
97%
Other

Infisical

Security · Devops

29,145

The open-source platform for secrets, certificates, privileged access, and AI agent security — all in one self-hostable system.

View details
91
Repo Health
84
Technical
65
Dependency
Built with
TypeScript97%
Updated yesterday
TypeScript
99%
Apache 2.0

Mastra Code

AI Code Assistants

27,743

"A coding agent that never compacts" — a terminal-based AI coding agent built on the Mastra framework, with Observational Memory instead of context compaction, multi-model support, and OAuth login for Claude Max or ChatGPT Plus.

View details
88
Repo Health
73
Technical
65
Dependency
Built with
TypeScript99%
Updated today
TypeScript
80%
Apache 2.0

nao

AI Development · Analytics

1,611

Build and deploy an open-source analytics agent that understands your data warehouse and answers business questions in plain English.

View details
84
Repo Health
76
Technical
67
Dependency
Built with
TypeScript80%
Python19%
Updated yesterday
TypeScript
99%
MIT

optio

AI Agents · AI Code Assistants

1,043

Self-hosted AI agent workflow orchestration that runs on your Kubernetes cluster — from ticket intake to squash-merged PR, entirely within your infrastructure.

View details
75
Repo Health
81
Technical
70
Dependency
Built with
TypeScript99%
Updated 3 weeks ago
TypeScript
62%
MIT

Scalar

Developer Tools

16,069

Beautiful, interactive OpenAPI documentation with a built-in offline-first API client and multi-language code generation — all in one open-source platform.

View details
89
Repo Health
89
Technical
65
Dependency
Built with
TypeScript62%
Vue32%
Updated 2 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search