Verdaccio is a lightweight, zero-dependency private npm registry that lets you host your own npm packages internally.

Let’s see it in action. Imagine you have a few internal libraries your company uses across multiple projects. Instead of publishing them to the public npm registry (which costs money and exposes your proprietary code), or managing complex file-based sharing, you can use Verdaccio.

Here’s a typical package.json for a project that uses an internal package named my-company-ui:

{
  "name": "my-app",
  "version": "1.0.0",
  "dependencies": {
    "react": "^18.2.0",
    "my-company-ui": "^2.1.0"
  }
}

When you run npm install (or yarn install), npm (or Yarn) will try to fetch my-company-ui from its configured registries. If Verdaccio is set up and pointed to, npm will first check Verdaccio for this package. If found, it downloads it; otherwise, it falls back to the public npm registry.

How Verdaccio Works Internally

At its core, Verdaccio acts as a proxy and a storage.

  1. Proxying: When a package isn’t found locally in Verdaccio, it can be configured to fetch it from an upstream registry (like registry.npmjs.org). This means your developers can install both private and public packages seamlessly through a single registry endpoint. Verdaccio caches these fetched packages locally.

  2. Storage: Verdaccio stores packages in a designated directory on the server. This storage can be as simple as a local filesystem folder, or it can be more advanced, using cloud object storage like AWS S3, Google Cloud Storage, or Azure Blob Storage.

  3. Authentication/Authorization: Verdaccio supports various authentication methods, from basic username/password to JWT, LDAP, and even integration with GitHub or other OAuth providers. This ensures only authorized users can publish or access private packages.

Key Configuration Levers

Verdaccio’s behavior is controlled by a single configuration file, typically config.yaml. Here are some critical sections:

  • storage: Defines where packages are stored.

    storage:
      local:
        directory: /var/verdaccio/storage
    

    This simple configuration uses the local filesystem. For S3, it would look like:

    storage:
      s3:
        bucket: my-private-npm-bucket
        region: us-east-1
        access_key: YOUR_ACCESS_KEY
        secret_key: YOUR_SECRET_KEY
    
  • auth: Configures how users authenticate.

    auth:
      htpasswd:
        file: /verdaccio/htpasswd
        # users:
        #   - user1: '$2b$10$...'
        #   - user2: '$2b$10$...'
    

    This uses a simple .htpasswd file. You can generate entries using htpasswd -c /verdaccio/htpasswd <username>.

  • uplinks: Defines upstream registries Verdaccio will proxy to.

    uplinks:
      npmjs:
        url: https://registry.npmjs.org/
        # optional:
        #  maxage: 20m # Cache duration for public packages
    

    This tells Verdaccio to fetch packages not found locally from registry.npmjs.org.

  • packages: This is where you define access rules for different package patterns.

    packages:
      '@my-company/*': # For all packages starting with @my-company/
        access: $authenticated # Only logged-in users can read
        publish: $admin        # Only admins can publish
        proxy: npmjs         # Use the 'npmjs' uplink if not found locally
      '**':                  # For all other packages
        access: $all         # Anyone can read (includes public packages from uplinks)
        publish: $anonymous    # No one can publish here (or configure specific roles)
        proxy: npmjs         # Use the 'npmjs' uplink
    

    The $authenticated and $admin are special placeholders that map to users defined in your auth section or provided by plugins.

Publishing a Private Package

Once Verdaccio is running and configured, publishing a private package is straightforward. First, configure npm to use your Verdaccio registry:

npm config set registry http://localhost:4873/

Then, log in:

npm login --registry http://localhost:4873/

(You’ll be prompted for your Verdaccio username, password, and email).

Finally, publish your package:

npm publish

Verdaccio will receive the package, store it, and make it available to other users configured to use your registry.

The most surprising true thing about Verdaccio is that its default configuration, running in memory with no persistence, can still serve as a functional, albeit temporary, private registry for quick testing or ephemeral environments.

The next logical step after setting up a basic Verdaccio instance is to explore advanced authentication mechanisms like LDAP or SAML for seamless integration with your existing identity provider.

Want structured learning?

Take the full Npm course →