npm

Private npm Registry Guide: Setup, Comparison & Best Practices

Complete guide to hosting private npm packages. Compare Verdaccio, GitHub Packages, npm Enterprise, and CloudRepo. Step-by-step setup for npm, Yarn, pnpm, and Bun.

CloudRepo Team
8 min read

Every JavaScript team eventually needs to share internal packages without publishing them to the public npm registry. Whether it’s proprietary business logic, shared UI components, or internal tooling, a private npm registry is the answer.

This guide covers why you need one, how the options compare, and step-by-step setup for npm, Yarn, pnpm, and Bun with CloudRepo.

Why Use a Private npm Registry?

Before evaluating solutions, let’s understand the problems a private registry solves.

Security and IP Protection

Your internal libraries contain proprietary code. Publishing them to the public npm registry exposes your intellectual property. A private registry keeps your packages secure behind authentication.

Terminal window
# These shouldn't be on public npm
npm install @acme/auth-sdk
npm install @acme/billing-core
npm install @acme/design-system

CI/CD Reliability

Depending on Git URLs or local tarballs creates fragile pipelines. A private registry provides stable, versioned packages that survive branch deletions, repository renames, and network hiccups.

Terminal window
# Fragile: depends on Git access and branch existence
npm install git+ssh://git@github.com/acme/shared-utils.git#main
# Reliable: versioned package from your registry
npm install @acme/shared-utils@2.1.0

Access Control

Control who can publish packages and who can install them. Per-user permissions and organization-level isolation keep your packages safe.

Reproducible Builds

Lock files reference registry URLs, not Git commits. A private registry ensures every npm install pulls the exact same artifacts, every time.

Comparing Private npm Registry Options

Verdaccio (Self-Hosted)

Verdaccio is the most popular open-source npm registry.

Pros:

  • Free and open source
  • Full npm compatibility
  • Proxy to public npm included
  • Active community

Cons:

  • You manage the infrastructure (servers, storage, backups, SSL)
  • No built-in high availability
  • Limited enterprise features (RBAC, audit logs)
  • Security patching is your responsibility

Best for: Small teams with DevOps capacity who want full control or need air-gapped environments.

GitHub Packages

GitHub’s built-in package registry supports npm alongside other formats.

Pros:

  • Integrated with GitHub repositories and Actions
  • Free for public packages
  • No additional accounts to manage

Cons:

  • Only supports scoped packages (@scope/package), not unscoped ones
  • Tied to GitHub ecosystem (vendor lock-in)
  • Storage and transfer limits on free tier
  • Data transfer fees on paid plans

Best for: Teams already on GitHub who only need scoped packages and want minimal configuration.

Important

GitHub Packages limitation: If you need to publish unscoped packages like my-utils (without an @scope/ prefix), GitHub Packages won’t work. CloudRepo supports both scoped and unscoped packages.

npm Enterprise (npmE)

npm’s own enterprise offering for private registries.

Pros:

  • From the npm team: maximum compatibility
  • SSO integration
  • Access management

Cons:

  • Expensive (custom, enterprise-tier pricing; npm doesn’t publish rates)
  • npm was acquired by GitHub, so the standalone enterprise product’s future is unclear
  • Overlap with GitHub Packages creates confusion

Best for: Large enterprises already invested in the npm ecosystem with budget for premium pricing.

JFrog Artifactory

The enterprise incumbent supporting 20+ package formats.

Pros:

  • Universal format support
  • Mature enterprise features
  • Virtual repositories for aggregation

Cons:

  • Consumption-based pricing creates unpredictable bills
  • Complex setup and administration
  • Expensive support contracts

Pricing reality: Artifactory’s $150/month base quickly escalates. With their consumption model (storage + transfer), moderate CI/CD usage can push costs to $600-1,200/month.

CloudRepo

Managed npm registry with transparent, predictable pricing.

Pros:

  • No egress fees: npm install never incurs transfer charges
  • Scoped AND unscoped packages (unlike GitHub Packages)
  • Works with npm, Yarn, pnpm, and Bun
  • Predictable flat-rate pricing
  • Support included from real engineers

Cons:

  • Fewer advanced features than Artifactory
  • No self-hosted option

Pricing: CloudRepo starts at $199/month with a generous transfer allowance and unlimited users.

Quick Comparison

Feature Verdaccio GitHub Packages Artifactory CloudRepo
Setup Time Hours Minutes Hours Minutes
Maintenance High None Medium None
Scoped Packages Yes Yes Yes Yes
Unscoped Packages Yes No Yes Yes
Egress Fees N/A Yes $0.75-1.25/GB None
SSO/SAML DIY GitHub only Extra cost Included
Support Community GitHub support Extra cost Included
Starting Price Free + infra Free (limited) $150/month + usage $199/month

Setting Up CloudRepo as Your Private npm Registry

Step 1: Create Your Repository

Sign up at cloudrepo.io/signup (14-day free trial, no credit card required) and create an npm repository through the web UI.

Your registry URL will be:

https://YOUR_ORG.mycloudrepo.io/repositories/YOUR_REPO

Step 2: Authenticate with npm

Terminal window
# Configure your registry, then run npm login
npm config set registry=https://YOUR_ORG.mycloudrepo.io/repositories/YOUR_REPO/
npm login

npm login opens your browser, walks you through CloudRepo sign-in, and writes a repo-scoped token to ~/.npmrc automatically. For CI/CD scripts, mint an API token in the admin portal and reference it as _authToken in .npmrc instead. No browser required.

Step 3: Configure .npmrc

After npm login, your ~/.npmrc is configured automatically. For project-local config (e.g., to share with your team):

.npmrc
registry=https://YOUR_ORG.mycloudrepo.io/repositories/YOUR_REPO/
always-auth=true

Step 4: Publish Your First Package

Terminal window
# Publish a scoped package
npm publish --access restricted
# Publish an unscoped package
npm publish

Step 5: Install from Your Registry

Terminal window
# Install works exactly like public npm
npm install @acme/shared-utils
npm install my-internal-tool

Working with Multiple Clients

CloudRepo uses the standard npm registry protocol, so all major JavaScript package managers work out of the box.

Yarn 2+ (Berry)

.yarnrc.yml
npmRegistryServer: 'https://YOUR_ORG.mycloudrepo.io/repositories/YOUR_REPO'
npmAlwaysAuth: true
npmAuthToken: '${NPM_TOKEN}'
Terminal window
# Install packages
yarn install
# Publish
yarn npm publish

pnpm

pnpm uses the standard .npmrc file:

.npmrc
registry=https://YOUR_ORG.mycloudrepo.io/repositories/YOUR_REPO
always-auth=true
//YOUR_ORG.mycloudrepo.io/repositories/YOUR_REPO:_authToken=${NPM_TOKEN}
Terminal window
# Install packages
pnpm install
# Publish
pnpm publish

Bun

bunfig.toml
[install]
registry = "https://YOUR_ORG.mycloudrepo.io/repositories/YOUR_REPO"

Or use .npmrc (Bun supports it):

Terminal window
# Install packages
bun install
# Publish (uses npm under the hood)
bunx npm publish

CI/CD Integration

GitHub Actions

.github/workflows/publish.yml
name: Publish Package
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://YOUR_ORG.mycloudrepo.io/repositories/YOUR_REPO'
- run: npm ci
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.CLOUDREPO_NPM_TOKEN }}

GitLab CI

.gitlab-ci.yml
publish:
image: node:20
stage: deploy
script:
- echo "//YOUR_ORG.mycloudrepo.io/repositories/YOUR_REPO:_authToken=${CLOUDREPO_NPM_TOKEN}" > .npmrc
- npm publish
only:
- tags

Jenkins

Jenkinsfile
pipeline {
agent { docker { image 'node:20' } }
stages {
stage('Publish') {
steps {
withCredentials([string(credentialsId: 'cloudrepo-npm-token', variable: 'NPM_TOKEN')]) {
sh '''
echo "//YOUR_ORG.mycloudrepo.io/repositories/YOUR_REPO:_authToken=${NPM_TOKEN}" > .npmrc
npm publish
'''
}
}
}
}
}

Best Practices

Scoped vs Unscoped Packages

Use scoped packages for organization-internal code and unscoped for shared libraries:

{
"name": "@acme/auth-sdk",
"version": "2.1.0"
}

Scoped packages make ownership clear and prevent naming collisions with public npm packages.

Use always-auth

Always set always-auth=true in your .npmrc. Without it, npm may attempt unauthenticated requests to your private registry and fail.

Per-Project .npmrc Over Global

Commit a .npmrc to each project rather than relying on global configuration. This ensures:

  • New developers can set up immediately
  • CI/CD environments work without extra configuration
  • Different projects can use different registries
.npmrc
registry=https://YOUR_ORG.mycloudrepo.io/repositories/YOUR_REPO
always-auth=true
# Auth token comes from environment variable — never commit tokens
//YOUR_ORG.mycloudrepo.io/repositories/YOUR_REPO:_authToken=${NPM_TOKEN}

Token Management

  • Generate read-only tokens for CI/CD install steps
  • Generate publish tokens only for release pipelines
  • Rotate tokens on a regular schedule
  • Never commit tokens to source control. Use environment variables.

Version Management with Dist-Tags

Use dist-tags to manage release channels:

Terminal window
# Publish a stable release (automatically tagged as "latest")
npm publish
# Publish a beta
npm publish --tag beta
# Promote beta to latest
npm dist-tag add @acme/sdk@2.0.0-beta.5 latest

Tip

CloudRepo supports the full npm dist-tag protocol. Use tags like beta, canary, and next to manage release channels without affecting production installs.

Getting Started

Ready to simplify your JavaScript package management?

  1. Start your 14-day free trial: no credit card required
  2. Create an npm repository: takes 30 seconds
  3. Run npm login: your browser opens, you authorize once, and your repo-scoped token lands in ~/.npmrc
  4. npm publish: your first package is live

No egress fees, no per-user pricing, no consumption meters. Just simple, reliable npm package hosting.


Questions about setting up your private npm registry? Our engineering team provides hands-on support for every customer. Contact us for a personalized walkthrough.

Ready for flat, predictable repository hosting?

Join the teams who've switched to CloudRepo for better pricing and features.