npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@verdaccio/plugin-verifier

v1.0.0-next-9.5

Published

Tool to verify that a Verdaccio plugin can be loaded and passes sanity checks

Readme

@verdaccio/plugin-verifier

A testing tool that verifies whether a Verdaccio plugin can be properly loaded, instantiated, and passes the required sanity checks for its category.

It uses asyncLoadPlugin from @verdaccio/loaders internally — the same loader Verdaccio uses at startup — so the verification is identical to what happens in production.

Available as both a CLI and a programmatic API.

This is a pure ESM package.

Install

npm install --save-dev @verdaccio/plugin-verifier

How It Works

When a plugin is verified, it runs through the same pipeline Verdaccio executes at boot time:

  1. Module resolution — can the plugin be found via require()?
  2. Export validation — does it export a function (CommonJS) or a class with a default export (ES6)?
  3. Instantiation — can the plugin be constructed with a config and plugin options?
  4. Sanity check — does the instance implement the required methods for its category?

Required Methods by Category

| Category | Required methods (at least one) | | ---------------- | ----------------------------------------------- | | authentication | authenticate, allow_access, allow_publish | | storage | getPackageStorage | | middleware | register_middlewares | | filter | filter_metadata |

CLI

The CLI is built with clipanion (the same framework used by @verdaccio/cli).

Usage

verdaccio-plugin-verifier <plugin> --category <category> [options]

Options

| Option | Description | | ---------------------- | ----------------------------------------------------------------------------------- | | --category, -c | (required) Plugin category: authentication, storage, middleware, filter | | --plugins-folder, -d | Absolute path to the plugins directory (maps to config.plugins) | | --prefix, -p | Plugin name prefix (default: verdaccio) |

Examples

Verify an auth plugin from a local plugins folder:

verdaccio-plugin-verifier my-auth --category authentication --plugins-folder /path/to/plugins

Verify a storage plugin installed via npm:

verdaccio-plugin-verifier my-storage --category storage

Verify a scoped plugin:

verdaccio-plugin-verifier @myorg/my-plugin --category middleware

Use a custom plugin prefix:

verdaccio-plugin-verifier auth --category authentication --prefix mycompany
# resolves to "mycompany-auth"

Exit Codes

| Code | Meaning | | ---- | --------------------------------------------------------- | | 0 | Plugin loaded and passed all checks | | 1 | Plugin failed to load, instantiate, or pass sanity checks |

CI Integration

Add a verification step to your plugin's CI pipeline:

# GitHub Actions example
- name: Verify plugin
  run: npx verdaccio-plugin-verifier my-auth --category authentication --plugins-folder ./build

Programmatic API

Verify a file-based plugin

Use pluginsFolder to point to the directory containing your plugin. The plugin folder must be prefixed with verdaccio- (or your custom prefix), matching the convention Verdaccio uses to resolve plugins from a folder.

plugins/
  verdaccio-my-auth/
    index.js
    package.json
import { PLUGIN_CATEGORY } from '@verdaccio/core';
import { verifyPlugin } from '@verdaccio/plugin-verifier';

const result = await verifyPlugin({
  pluginPath: 'my-auth',
  category: PLUGIN_CATEGORY.AUTHENTICATION,
  pluginsFolder: '/absolute/path/to/plugins',
});

if (result.success) {
  console.log(`Plugin loaded successfully (${result.pluginsLoaded} instance(s))`);
} else {
  console.error('Plugin verification failed:', result.error);
}

Verify an npm-installed plugin

When pluginsFolder is omitted, the loader resolves the plugin from node_modules using Node's require algorithm, exactly as Verdaccio does in production.

// Unscoped: looks for `verdaccio-my-auth` in node_modules
const result = await verifyPlugin({
  pluginPath: 'my-auth',
  category: PLUGIN_CATEGORY.AUTHENTICATION,
});

// Scoped: looks for `@myorg/my-auth` as-is
const result = await verifyPlugin({
  pluginPath: '@myorg/my-auth',
  category: PLUGIN_CATEGORY.AUTHENTICATION,
});

Use in tests (vitest / jest)

This is the primary use case — add a test in your plugin repository to ensure it can be loaded by Verdaccio:

import { describe, expect, it } from 'vitest';

import { PLUGIN_CATEGORY } from '@verdaccio/core';
import { verifyPlugin } from '@verdaccio/plugin-verifier';

describe('my verdaccio plugin', () => {
  it('should be loadable by verdaccio', async () => {
    const result = await verifyPlugin({
      pluginPath: 'my-auth',
      category: PLUGIN_CATEGORY.AUTHENTICATION,
      pluginsFolder: '/path/to/build/output',
    });

    expect(result.success).toBe(true);
    expect(result.pluginsLoaded).toBe(1);
  });
});

Pass plugin configuration

If your plugin requires configuration to instantiate, pass it via pluginConfig:

const result = await verifyPlugin({
  pluginPath: 'my-storage',
  category: PLUGIN_CATEGORY.STORAGE,
  pluginsFolder: '/path/to/plugins',
  pluginConfig: {
    dataDir: '/tmp/verdaccio-storage',
    maxSize: 1024,
  },
});

Custom sanity check

Override the default sanity check to verify additional methods specific to your plugin:

const result = await verifyPlugin({
  pluginPath: 'my-auth',
  category: PLUGIN_CATEGORY.AUTHENTICATION,
  pluginsFolder: '/path/to/plugins',
  sanityCheck: (plugin) => {
    return typeof plugin.authenticate === 'function' && typeof plugin.changePassword === 'function';
  },
});

Custom plugin prefix

If your Verdaccio instance uses a custom plugin prefix (via server.pluginPrefix in config.yaml), pass it to the verifier:

const result = await verifyPlugin({
  pluginPath: 'auth',
  category: PLUGIN_CATEGORY.AUTHENTICATION,
  pluginsFolder: '/path/to/plugins',
  prefix: 'mycompany', // looks for "mycompany-auth" instead of "verdaccio-auth"
});

API Reference

verifyPlugin(options: VerifyPluginOptions): Promise<VerifyResult>

VerifyPluginOptions

| Property | Type | Default | Description | | --------------- | -------------------------- | ---------------- | --------------------------------------------------------------------------------------------------------- | | pluginPath | string | (required) | Plugin identifier as it would appear in config.yaml (e.g. my-auth, @scope/my-plugin) | | category | PluginCategory | (required) | Plugin category: authentication, storage, middleware, or filter | | pluginConfig | Record<string, unknown> | {} | Configuration passed to the plugin constructor | | sanityCheck | (plugin: any) => boolean | (per category) | Custom validation function; overrides the built-in check | | prefix | string | 'verdaccio' | Plugin name prefix (maps to server.pluginPrefix) | | pluginsFolder | string | undefined | Absolute path to plugins directory (maps to config.plugins); when omitted, resolves from node_modules |

VerifyResult

| Property | Type | Description | | --------------- | ---------------- | ----------------------------------------------- | | success | boolean | Whether the plugin loaded and passed all checks | | pluginName | string | The plugin identifier used | | category | PluginCategory | The category verified against | | pluginsLoaded | number | Number of plugin instances successfully loaded | | error | string? | Error message if verification failed |

Sanity Check Helpers

Individual sanity check functions are also exported for direct use:

import {
  authSanityCheck,
  filterSanityCheck,
  getSanityCheck,
  // returns the right check for a given category
  middlewareSanityCheck,
  storageSanityCheck,
} from '@verdaccio/plugin-verifier';

License

MIT