or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-fastify-plugin

Plugin helper for Fastify that adds skip-override property, validates Fastify version requirements, and manages plugin metadata including names, dependencies, and decorators.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/fastify-plugin@5.0.x

To install, run

npx @tessl/cli install tessl/npm-fastify-plugin@5.0.0

index.mddocs/

Fastify Plugin

Fastify Plugin is a utility library that provides a standardized wrapper for creating Fastify plugins with proper encapsulation control, dependency management, and version compatibility validation. It automatically adds the skip-override property to break encapsulation when needed, validates minimum Fastify version requirements, and manages plugin metadata including names, dependencies, and decorators.

Package Information

  • Package Name: fastify-plugin
  • Package Type: npm
  • Language: JavaScript with TypeScript definitions
  • Installation: npm install fastify-plugin

Core Imports

const fp = require('fastify-plugin');

For TypeScript/ESM:

import fp from 'fastify-plugin';
// or
import { fastifyPlugin } from 'fastify-plugin';

Basic Usage

const fp = require('fastify-plugin');

// Callback-based plugin
module.exports = fp(function (fastify, opts, done) {
  // Plugin logic here
  fastify.decorate('utility', () => 'helper function');
  done();
});

// Async plugin
module.exports = fp(async function (fastify, opts) {
  // Plugin logic here
  fastify.decorate('utility', () => 'helper function');
});

// With metadata options
module.exports = fp(function (fastify, opts, done) {
  // Plugin logic here
  done();
}, {
  name: 'my-plugin',
  fastify: '5.x',
  dependencies: ['other-plugin']
});

Capabilities

Plugin Wrapper Function

The main fastifyPlugin function wraps a plugin function to add necessary metadata and control encapsulation behavior.

/**
 * Wraps a plugin function with metadata and encapsulation control
 * @param {Function} fn - The plugin function (FastifyPluginCallback or FastifyPluginAsync)
 * @param {Object|string} [options={}] - Plugin metadata options or Fastify version string
 * @returns {Function} The wrapped plugin function with added metadata
 */
function fastifyPlugin(fn, options);

Alternative export patterns:

// Available as default export
const fp = require('fastify-plugin');

// Available as named export
const { fastifyPlugin } = require('fastify-plugin');

// Available as .default property
const fp = require('fastify-plugin').default;

Plugin Metadata Options

Configuration object for specifying plugin requirements and dependencies.

interface PluginMetadata {
  /** Bare-minimum version of Fastify for your plugin (semver range) */
  fastify?: string;
  /** Plugin name for dependency validation and collision prevention */
  name?: string;
  /** Decorator dependencies for this plugin */
  decorators?: {
    fastify?: (string | symbol)[];
    reply?: (string | symbol)[];
    request?: (string | symbol)[];
  };
  /** The plugin dependencies by name */
  dependencies?: string[];
  /** Whether to maintain encapsulation (default: false) */
  encapsulate?: boolean;
}

Usage Examples:

// Version requirement only
fp(plugin, '5.x');

// Full metadata
fp(plugin, {
  name: 'my-awesome-plugin',
  fastify: '5.x',
  decorators: {
    fastify: ['utility', 'helper'],
    reply: ['serialize'],
    request: ['validate']
  },
  dependencies: ['fastify-cors', 'fastify-helmet'],
  encapsulate: false
});

// Encapsulated plugin
fp(plugin, {
  name: 'encapsulated-plugin',
  encapsulate: true
});

TypeScript Generic Function

Strongly typed wrapper for TypeScript projects with full generic type support.

declare function fastifyPlugin<
  Options extends FastifyPluginOptions = Record<never, never>,
  RawServer extends RawServerBase = RawServerDefault,
  TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
  Logger extends FastifyBaseLogger = FastifyBaseLogger,
  Fn extends FastifyPluginCallback<Options, RawServer, TypeProvider, Logger> | FastifyPluginAsync<Options, RawServer, TypeProvider, Logger> = FastifyPluginCallback<Options, RawServer, TypeProvider, Logger>
>(
  fn: Fn extends unknown ? Fn extends (...args: any) => Promise<any> ? FastifyPluginAsync<Options, RawServer, TypeProvider, Logger> : FastifyPluginCallback<Options, RawServer, TypeProvider, Logger> : Fn,
  options?: PluginMetadata | string
): Fn;

TypeScript Usage:

import { FastifyPluginAsync, FastifyPluginCallback } from 'fastify';
import fp from 'fastify-plugin';

// Typed callback plugin
const callbackPlugin: FastifyPluginCallback = (fastify, options, done) => {
  fastify.decorate('utility', () => 'helper');
  done();
};
export default fp(callbackPlugin);

// Typed async plugin
const asyncPlugin: FastifyPluginAsync = async (fastify, options) => {
  fastify.decorate('utility', () => 'helper');
};
export default fp(asyncPlugin);

Plugin Behavior

Encapsulation Control

By default, fastify-plugin adds the skip-override symbol to break Fastify's encapsulation, making plugin decorators available in the parent context:

// Without fastify-plugin - decorators are encapsulated
fastify.register(function (fastify, opts, done) {
  fastify.decorate('utility', () => 'helper');
  done();
});
// fastify.utility is undefined here

// With fastify-plugin - decorators are available in parent scope
fastify.register(fp(function (fastify, opts, done) {
  fastify.decorate('utility', () => 'helper');
  done();
}));
// fastify.utility is available here

Automatic Plugin Naming

If no name is provided, fastify-plugin automatically generates one from the function name or file path:

function myCustomPlugin(fastify, opts, done) {
  done();
}

// Automatic name: "myCustomPlugin"
fp(myCustomPlugin);

// Anonymous functions get auto-generated names with counter
fp(function (fastify, opts, done) { done(); });
// Name: "anonymous-auto-0", "anonymous-auto-1", etc.

Version Validation

The plugin validates Fastify version compatibility using semver ranges:

// Requires Fastify 5.x
fp(plugin, { fastify: '5.x' });

// Requires Fastify 4.x or 5.x
fp(plugin, { fastify: '>=4.0.0 <6.0.0' });

// Just version string
fp(plugin, '5.x');

Error Handling

The plugin validates inputs and throws descriptive errors:

// TypeError: fastify-plugin expects a function, instead got a 'string'
fp('not a function');

// TypeError: The options object should be an object
fp(plugin, []);

// TypeError: fastify-plugin expects a version string, instead got 'number'
fp(plugin, { fastify: 123 });

Advanced Features

Module Pattern Support

Fastify-plugin supports various module patterns for better compatibility:

// Adds .default property for ESM compatibility
const wrappedPlugin = fp(plugin);
// wrappedPlugin.default === wrappedPlugin

// Adds camelCase property for TypeScript named imports
fp(plugin, { name: 'my-awesome-plugin' });
// Creates plugin.myAwesomePlugin property

Dependency Validation

Plugins can declare dependencies on other plugins and decorators:

fp(plugin, {
  name: 'my-plugin',
  dependencies: ['fastify-cors'], // Requires fastify-cors to be registered first
  decorators: {
    fastify: ['authenticate'], // Requires authenticate decorator on fastify instance
    reply: ['serialize'],      // Requires serialize decorator on reply
    request: ['validate']      // Requires validate decorator on request
  }
});

Scoped Package Name Handling

Properly handles scoped npm package names in camelCase conversion:

// @myorg/my-plugin becomes myorgMyPlugin
fp(plugin, { name: '@myorg/my-plugin' });

Types

PluginOptions (Deprecated)

/**
 * @deprecated Use PluginMetadata instead
 */
interface PluginOptions extends PluginMetadata {}

Symbols and Metadata

The plugin adds several symbols and properties to wrapped functions:

// Internal symbols added by fastify-plugin
Symbol.for('skip-override')      // Controls encapsulation
Symbol.for('fastify.display-name') // Plugin display name
Symbol.for('plugin-meta')        // Complete plugin metadata