Skip to content
cccskills
FreePublished on GitHub

plugins

Maintain Verdaccio’s bundled plugins and investigate loading failures using checks that identify resolution, export, construction, or interface problems. Review shared plugin interfaces for compatibility, update affected plugins, and validate fixes with plugin and integration tests.

OriginalShow the original description

Maintain the plugins bundled in this repository (htpasswd, local-storage, auth-memory, memory, audit, package-filter, ui-theme) and the plugin contracts in @verdaccio/core — fix a bundled plugin, change a pluginUtils interface safely, diagnose why a plugin does not load, or verify a plugin with @verdaccio/plugin-verifier. Use when a task touches packages/plugins, packages/loaders, pluginUtils, or a plugin loading problem. Requests to add a new bundled plugin are gated on an accepted discussion thread; this skill says how to handle them.

See how to install

Good for

  • Diagnosing why a plugin fails to load
  • Fixing bundled authentication or storage plugins
  • Checking compatibility when changing plugin interfaces
  • Validating plugin loading with @verdaccio/plugin-verifier

Files included (1)

  • SKILL.md11.7 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Plugins

This repository ships a small set of bundled plugins and owns the contracts every third-party plugin implements. The work here is maintenance: fixing the bundled plugins, keeping the contracts stable, and making sure plugins load. Writing a new plugin is not repository work.

New plugins are not accepted without a discussion first

A PR that adds a new bundled plugin under packages/plugins is not accepted unless an accepted discussion thread exists for it in the repository's GitHub Discussions (https://github.com/verdaccio/verdaccio/discussions, category Ideas). The discussion settles whether the capability belongs in core, in a bundled plugin, or in an external package, and who maintains it. When asked to add a bundled plugin:

  • Look for the discussion and read the maintainers' conclusion. Without one, do not start the PR; report that the change needs a discussion thread first and what it should argue (the problem, why configuration and existing plugins do not cover it, the maintenance cost).
  • With an accepted discussion, link it from the PR body and follow "Adding a bundled plugin" below.

New third-party plugins live in their own repositories, outside this one. Point people to the website docs (https://verdaccio.org/docs/plugins and the plugin-auth, plugin-storage, plugin-middleware, plugin-filter, plugin-theme pages); the contracts below are the same, and @verdaccio/plugin-verifier checks the result. The scaffolding tools for external plugins are not used in this repository.

The bundled plugins

PackagePathCategoryNotes
verdaccio-htpasswdpackages/plugins/htpasswdauthenticationDefault auth in default.yaml; file resolved relative to configPath
@verdaccio/local-storagepackages/plugins/local-storagestorageDefault storage; the production reference for StorageHandler
verdaccio-auth-memorypackages/plugins/auth-memoryauthenticationSmallest complete auth plugin; the reference for the auth chain
verdaccio-memorypackages/plugins/memorystorageIn-memory storage used by tests; smallest complete storage plugin
verdaccio-auditpackages/plugins/auditmiddlewarenpm audit proxy; loaded by default when no middleware is configured
@verdaccio/package-filterpackages/plugins/package-filterfilterRegistered under its scoped name in filters:
@verdaccio/ui-themepackages/plugins/ui-themethemeThe default web UI; consumed as a published dependency by every line

packages/tools/verdaccio-*-fake-plugin are test fixtures for the loader, not plugins to maintain.

The contracts

The interfaces live in packages/core/core/src/plugin-utils.ts (pluginUtils), the shared types in @verdaccio/types. Every plugin extends pluginUtils.Plugin<Config> and is constructed as (pluginConfig, { config, logger }).

CategoryConfig sectionInterfaceSanity check (loader refuses the plugin without it)
authenticationauth:Auth<Config>one of authenticate, allow_access, allow_publish
storagestore:Storage<Config> + StorageHandlergetPackageStorage
middlewaremiddlewares:ExpressMiddleware<Config, Storage, Auth>register_middlewares
filterfilters:ManifestFilter<Config>filter_metadata
themetheme:object with staticPath, manifest, manifestFilesall three properties

Changing a contract is a breaking change for every third-party plugin. Adding an optional method (as allow_stage was added) is backwards compatible; renaming, removing, changing a signature, or turning a callback into a promise is major: it needs a major changeset, an entry in docs/migrations-guide.md, the bundled plugins updated in the same PR, and a look at the external plugins the organisation maintains (verdaccio-aws-s3-storage, verdaccio-google-cloud, verdaccio-azure, verdaccio-auth-ldap, ...) so they can be ported. The loader's sanity checks in plugin-utils.ts are part of the contract too.

Semantics the bundled plugins rely on and that a fix must preserve:

  • Auth chain. Plugins run in config order; authenticate answers cb(null, groups) on success, cb(null, false) to let the next plugin try, and a VerdaccioError (errorUtils.getUnauthorized(API_ERROR.BAD_USERNAME_PASSWORD)) to stop. The allow_* methods honour $all, $anonymous, $authenticated, and the user's groups exactly as auth-memory does; a change there alters package-access rules for every deployment.
  • Storage. StorageHandler is promise-based; readTarball/writeTarball return Node streams and receive an AbortSignal; writes are atomic and fail-safe; updatePackage(name, async manifest => manifest) serialises concurrent updates to the same manifest; a failed writeTarball leaves nothing behind. Only one storage plugin is used (the first loaded, with a warning).
  • Middleware. register_middlewares(app, auth, storage) mounts routes on the Express app; protect them with auth.apiJWTmiddleware() rather than parsing tokens. audit is the default when middlewares: is empty.
  • Filter. filter_metadata(manifest) returns a new manifest and runs on every packument read; package-filter shows the versions/time/dist-tags/_distfiles cleanup that must stay consistent.
  • Theme. A factory returning { staticPath, manifest, manifestFiles: { js, css } }; only the first theme is used.

How plugins load

asyncLoadPlugin in packages/loaders/src/plugin-async-loader.ts is the only loader, used by auth, store (storage and filters), server/express (middleware) and web (theme), and by @verdaccio/plugin-verifier:

  • Key foo resolves to package verdaccio-foo (verdaccio-theme-foo for themes); server.pluginPrefix replaces the prefix. A scoped key is used verbatim.
  • With plugins: ./plugins in the config, <plugins dir>/<package name> is tried first (relative to the config file, so configPath must be set), then Node resolution from node_modules.
  • The export is a default class (new plugin.default(config, options)) or a CJS factory function. require() is tried first, import() second; the entry point for a folder is read from exports['.'], then module, then main.
  • A plugin that fails the category's sanity check is logged and skipped; the registry keeps starting. A throwing constructor is only guaranteed to be caught this way when loaded from a configured plugins: folder (that path wraps executePlugin in a try/catch); the npm-resolved (node_modules) path calls executePlugin unguarded, so a throwing constructor there currently propagates out of asyncLoadPlugin instead of being skipped — a known loader gap, not a guarantee.

Loader changes are tested in packages/loaders/test and through every bundled plugin's plugin-load.spec.ts; run both.

Diagnosing "plugin not loaded"

Run the verifier first: verdaccio-plugin-verifier <key> --category <category> [--plugins-folder <abs path>] [--prefix <prefix>], or verifyPlugin({ pluginPath, category, pluginsFolder, prefix, pluginConfig, configPath }) from @verdaccio/plugin-verifier. Its diagnostics name the failing phase: resolve, export, instantiate, or sanity-check. Then check, in order: the key-to-name mapping and pluginPrefix, the plugins: folder versus node_modules resolution, the export shape, a throwing constructor or a missing dependency of the plugin, and the sanity check. The loader logs package not found for resolution problems, error loading plugin for constructor and dependency errors, and doesn't look like a valid plugin for a sanity failure; DEBUG=verdaccio:plugin:* verdaccio prints every step.

A "plugin not loaded" report from a user is usually one of these, not a loader bug; triage it against this list before opening the loader.

Fixing a bundled plugin

  1. Reproduce with the plugin's own tests (pnpm --filter <pkg> test) or a config that registers it, started with node packages/verdaccio/bin/verdaccio --config <yaml>.
  2. Fix in the plugin, not by special-casing it in store, auth, or server: a bundled plugin gets no privilege a third-party plugin cannot have.
  3. Tests: unit tests instantiate the class with a config object and a fake logger (see packages/plugins/auth-memory/test/index.spec.ts; new Config(getDefaultConfig()) from @verdaccio/config for the app config), and every bundled plugin keeps a plugin-load.spec.ts through verifyPlugin. Auth and middleware changes get an integration test through initializeServer from @verdaccio/test-helper; storage changes run the store tests and the e2e CLI battery (./scripts/e2e-cli-local.sh npm@11).
  4. Rebuild the plugin before testing anything that consumes it (build/ is what other packages import), then follow the testing-changes skill.
  5. One changeset for the PR, naming the plugin package (and @verdaccio/core when a contract moved). htpasswd, audit, and package-filter are dependencies of the verdaccio package and ship with every release; ui-theme is in the fixed version group.
  6. Port to 6.x/8.x when the bug exists there; the plugin sources differ between lines, so re-run that line's tests rather than cherry-picking blindly.

Plugin configuration is not validated by core: a plugin validates its own section in the constructor and fails there with a clear message, never on the first request, and it does not read process.env for what belongs in the YAML. Never log credentials, debug output included.

Adding a bundled plugin (only with an accepted discussion)

Mirror packages/plugins/auth-memory: vite.config.mjs calling createLibConfig from the root vite.lib.config.mjs, tsconfig.json and tsconfig.build.json extending the base, package.json with build/watch/test/clean scripts and exports pointing at build/, @verdaccio/core as a workspace: dependency, a types.ts for the plugin's config, a README with the config snippet. Then add the folder to pnpm-workspace.yaml, pnpm install, build it, register it where the discussion decided (default.yaml, packages/verdaccio/package.json), add the unit and plugin-load.spec.ts tests, a minor changeset for the new package, and link the discussion from the PR body.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

implement-change

FreeSummary

Implement Verdaccio fixes, features, or refactoring after checking whether existing settings or plugins already solve the problem. Place changes in the responsible component, reuse helpers, add tests and release notes, and validate affected packages.

  • Implementing a bug fix with a regression test
  • Checking existing settings before adding a feature
  • Refactoring code within a defined change
verdaccio/verdaccio17.9KUpdated Oct 18, 2026

pr-labels

FreeSummary

Select existing labels for Verdaccio pull requests based on the target release line and the substance of the change. Apply them when authorized, or report exact recommendations when reviewing someone else's PR or lacking permission.

  • Adding labels immediately after creating a PR
  • Reviewing missing or incorrect PR labels
  • Choosing labels for a release-line port
verdaccio/verdaccio17.9KUpdated Oct 18, 2026

pull-requests

FreeSummary

Guide a Verdaccio change through a pull request, from branch preparation and checks to changelog entries, labels, CI results, and review responses. Track separate pull requests when the fix also belongs on other release lines.

  • Preparing and opening a pull request
  • Investigating failed CI checks after a push
  • Addressing review comments and updating the PR
verdaccio/verdaccio17.9KUpdated Oct 18, 2026

review-code

FreeSummary

Review Verdaccio code changes for security, package manager compatibility, performance, and maintainability. Verify concerns against surrounding code and relevant tests, then report actionable issues with their location, trigger, impact, and supporting evidence.

  • Reviewing local changes before opening a pull request
  • Checking security and package manager compatibility
  • Tracing error handling and performance concerns
verdaccio/verdaccio17.9KUpdated Oct 18, 2026

review-pr

FreeSummary

Assess an existing Verdaccio pull request by checking code changes, automated checks, review feedback, release notes, and supported release branches. Receive a verified report explaining whether it is ready to merge and what needs attention.

  • Reviewing a pull request before merging
  • Rechecking human and automated review feedback
  • Checking release notes and release branch coverage
verdaccio/verdaccio17.9KUpdated Oct 18, 2026

testing-changes

FreeSummary

Choose and run checks that cover a Verdaccio change, including affected packages, dependent packages, API tests, and relevant client or UI flows. Rebuild first and report coverage limits so passing results reflect the edited code.

  • Verifying changes before committing or pushing
  • Selecting tests for affected packages and their dependents
  • Checking package manager or UI behavior
verdaccio/verdaccio17.9KUpdated Oct 18, 2026

See all skills by verdaccio

Report a problem with this skill