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-aws-s3-storage

v12.0.2

Published

AWS S3 storage implementation for Verdaccio

Readme

verdaccio-aws-s3-storage

AWS S3 + DynamoDB storage plugin for Verdaccio.

Uses S3 for package tarballs and metadata, and DynamoDB for the registry database (package list, secrets, tokens).

Built with AWS SDK for JavaScript v3.

Requirements

  • Node.js >= 24
  • Verdaccio >= 7.x
  • AWS S3 Bucket — stores package tarballs and package.json metadata
  • AWS DynamoDB Table — stores the registry state (package list, secret, auth tokens)
    • Partition key: pk (String)
    • Sort key: sk (String)
    • Billing mode: PAY_PER_REQUEST (recommended) or provisioned
  • AWS Credentials — via environment variables, IAM role, instance profile, or explicit config

IAM Permissions

The plugin requires the following IAM permissions:

S3:

  • s3:GetObject
  • s3:PutObject
  • s3:DeleteObject
  • s3:DeleteObjects (for bulk deletes)
  • s3:ListBucket / s3:ListObjectsV2
  • s3:HeadObject

DynamoDB:

  • dynamodb:GetItem
  • dynamodb:PutItem
  • dynamodb:DeleteItem
  • dynamodb:Query

Installation

npm install verdaccio-aws-s3-storage

Configuration

Add to your Verdaccio config.yaml:

store:
  aws-s3-storage:
    bucket: your-s3-bucket
    keyPrefix: some-prefix # optional, nests all files under a subdirectory
    region: us-east-1 # optional, defaults to AWS SDK default
    endpoint: https://s3.us-east-1.amazonaws.com # optional
    s3ForcePathStyle: false # optional, required for MinIO/LocalStack
    tarballACL: private # optional, use 'public-read' for CDN (e.g. CloudFront)
    accessKeyId: your-key # optional, uses AWS credential chain if omitted
    secretAccessKey: your-secret # optional
    sessionToken: your-token # optional
    proxy: https://your-proxy # optional

    # DynamoDB (required)
    dynamoTableName: verdaccio-registry
    dynamoEndpoint: https://dynamodb.us-east-1.amazonaws.com # optional
    dynamoRegion: us-east-1 # optional, defaults to 'region'

Environment variable substitution

Config values can reference environment variables by name. If the environment variable is set, its value is used; otherwise the literal string is used as-is.

store:
  aws-s3-storage:
    bucket: AWS_S3_BUCKET # uses $AWS_S3_BUCKET if set, otherwise literal "AWS_S3_BUCKET"
    keyPrefix: AWS_S3_KEY_PREFIX
    region: AWS_DEFAULT_REGION
    endpoint: AWS_S3_ENDPOINT
    accessKeyId: AWS_ACCESS_KEY_ID
    secretAccessKey: AWS_SECRET_ACCESS_KEY
    sessionToken: AWS_SESSION_TOKEN
    dynamoTableName: AWS_DYNAMO_TABLE_NAME
    dynamoEndpoint: AWS_DYNAMO_ENDPOINT
    dynamoRegion: AWS_DYNAMO_REGION

Environment variables reference

The following environment variables are used by the Docker image and the plugin when config values reference them:

S3

| Variable | Required | Description | | -------------------- | -------- | ---------------------------------------------------------------------------------------- | | AWS_S3_BUCKET | Yes | S3 bucket name for storing packages | | AWS_S3_KEY_PREFIX | No | Prefix (subdirectory) for all S3 keys. Default: none | | AWS_S3_ENDPOINT | No | Custom S3 endpoint URL. Required for LocalStack or MinIO. Omit for real AWS | | AWS_DEFAULT_REGION | No | AWS region for S3 and DynamoDB (if AWS_DYNAMO_REGION is not set). Default: SDK default |

DynamoDB

| Variable | Required | Description | | ----------------------- | -------- | ------------------------------------------------------------------------ | | AWS_DYNAMO_TABLE_NAME | Yes | DynamoDB table name (must have pk/sk key schema) | | AWS_DYNAMO_ENDPOINT | No | Custom DynamoDB endpoint URL. Required for LocalStack. Omit for real AWS | | AWS_DYNAMO_REGION | No | AWS region for DynamoDB. Falls back to AWS_DEFAULT_REGION |

Authentication

| Variable | Required | Description | | ----------------------- | -------- | ----------------------------------------------------------------- | | AWS_ACCESS_KEY_ID | No | AWS access key. Omit to use IAM roles, instance profiles, or IRSA | | AWS_SECRET_ACCESS_KEY | No | AWS secret key. Required if AWS_ACCESS_KEY_ID is set | | AWS_SESSION_TOKEN | No | AWS session token for temporary credentials (STS) |

Debug

| Variable | Required | Description | | -------- | -------- | ---------------------------------------------------------------------------------------------------------------- | | DEBUG | No | Enable debug output. Set to verdaccio:plugin* for all plugin namespaces |

Available debug namespaces:

  • verdaccio:plugin:aws-s3-storage:database — DynamoDB operations (add, remove, get, tokens, secret)
  • verdaccio:plugin:aws-s3-storage:package — S3 package operations (read, write, create, delete, tarballs)
  • verdaccio:plugin:aws-s3-storage:s3-client — S3 client initialization
  • verdaccio:plugin:aws-s3-storage:dynamo-client — DynamoDB client initialization
  • verdaccio:plugin:aws-s3-storage:delete-prefix — S3 prefix deletion
  • verdaccio:plugin:aws-s3-storage:errors — AWS error conversion
  • verdaccio:plugin:aws-s3-storage:config — config value resolution from env vars

Custom storage per package scope

packages:
  '@scope/*':
    access: $all
    publish: $all
    storage: 'scoped' # stored under keyPrefix/scoped/@scope/pkg/
  '**':
    access: $all
    publish: $all
    proxy: npmjs
    storage: 'public'

Tarball ACL

Set tarballACL: public-read to grant anonymous read access for CDN integration (e.g. Amazon CloudFront).

Architecture

                   +-----------+
                   | Verdaccio |
                   +-----+-----+
                         |
            +------------+------------+
            |                         |
      S3Database               S3PackageManager
      (registry state)         (per-package storage)
            |                         |
       DynamoDB                      S3
   +-----------------+      +------------------+
   | pk=CONFIG       |      | pkg/package.json |
   | pk=PACKAGE      |      | pkg/tarball.tgz  |
   | pk=TOKEN#user   |      +------------------+
   +-----------------+

S3Database handles registry operations via DynamoDB:

  • Package list (add, remove, get)
  • Secret management (getSecret, setSecret)
  • Auth tokens (saveToken, deleteToken, readTokens)

S3PackageManager handles per-package operations via S3:

  • Package metadata (readPackage, savePackage, createPackage, deletePackage)
  • Tarballs (readTarball, writeTarball)

DynamoDB table schema

Single-table design with partition key pk and sort key sk:

| pk | sk | Description | | -------------- | --------------- | ------------------- | | CONFIG | SECRET | Registry secret key | | PACKAGE | {packageName} | Package entry | | TOKEN#{user} | {tokenKey} | Auth token |

Development

See LOCAL_DEV.md for the full local development guide, including:

  • Setup, build, test, and lint commands
  • Running Verdaccio + LocalStack via Docker Compose
  • Inspecting S3 and DynamoDB data in LocalStack
  • Debug logging namespaces
  • Helm + LocalStack example for Kubernetes

Creating the DynamoDB table (production)

AWS CLI

aws dynamodb create-table \
  --table-name verdaccio-registry \
  --attribute-definitions \
    AttributeName=pk,AttributeType=S \
    AttributeName=sk,AttributeType=S \
  --key-schema \
    AttributeName=pk,KeyType=HASH \
    AttributeName=sk,KeyType=RANGE \
  --billing-mode PAY_PER_REQUEST

Terraform

resource "aws_dynamodb_table" "verdaccio" {
  name         = "verdaccio-registry"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "pk"
  range_key    = "sk"

  attribute {
    name = "pk"
    type = "S"
  }

  attribute {
    name = "sk"
    type = "S"
  }
}

CloudFormation

Resources:
  VerdaccioTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: verdaccio-registry
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: pk
          AttributeType: S
        - AttributeName: sk
          AttributeType: S
      KeySchema:
        - AttributeName: pk
          KeyType: HASH
        - AttributeName: sk
          KeyType: RANGE

Scaling & Production Deployment

The plugin is fully stateless and supports horizontal scaling. Run multiple Verdaccio instances behind a load balancer — all instances share the same S3 bucket and DynamoDB table.

  • Scaling guide — architecture, concurrency safety, ECS/Fargate, Kubernetes, monitoring, cost estimation
  • Helm example — deploy on Kubernetes using the official Verdaccio Helm chart with IRSA support

License

MIT