npm Monorepo Publishing Guide

Publishing packages from a monorepo requires tooling for version management, dependency ordering, and release automation. This guide covers the major tools and strategies for publishing monorepo packages to npm.

Monorepo Publishing Tools

Several tools handle the complexity of publishing multiple packages from a single repository. Each has trade-offs in terms of flexibility, complexity, and ecosystem integration.

Changesets

A tool for managing versioning and changelogs in multi-package repositories. Popular in the JavaScript ecosystem and integrates well with GitHub Actions.

Pros

  • + Excellent GitHub integration
  • + Supports both fixed and independent versioning
  • + Generates changelogs automatically
  • + Works with any package manager

Cons

  • - Requires manual changeset creation
  • - Learning curve for contributors
  • - No built-in task runner
Documentation →

Lerna

The original monorepo tool for JavaScript. Now maintained by Nx, it handles versioning, publishing, and running commands across packages.

Pros

  • + Mature and battle-tested
  • + Good for legacy monorepos
  • + Integrated with Nx for caching
  • + Supports both versioning modes

Cons

  • - Complex configuration
  • - Slower than newer alternatives
  • - Less active community
Documentation →

Turborepo

A high-performance build system for JavaScript monorepos. Focused on task running and caching, but works well with Changesets for publishing.

Pros

  • + Extremely fast with caching
  • + Simple configuration
  • + Great developer experience
  • + Remote caching available

Cons

  • - No built-in publishing (use with Changesets)
  • - Smaller ecosystem than Lerna
  • - Some features require Vercel account
Documentation →

pnpm + workspace

pnpm's built-in workspace feature with publish command. Lightweight option for teams already using pnpm.

Pros

  • + No extra dependencies
  • + Fast and disk-efficient
  • + Simple workspace protocol
  • + Good npm compatibility

Cons

  • - Manual version management
  • - No changelog generation
  • - Less automation than dedicated tools
Documentation →

Versioning Strategies

How you version packages affects release frequency, dependency management, and user expectations.

Fixed Versioning

All packages share the same version number. When any package changes, all versions bump together.

Best for: Tightly coupled packages, frameworks, libraries meant to be used together

Independent Versioning

Each package has its own version. Only changed packages get version bumps.

Best for: Loosely coupled packages, plugin ecosystems, packages with different release cycles

Recommendation: Start with fixed versioning for simplicity. Move to independent versioning when you have packages with genuinely different release cycles or when unnecessary version bumps become problematic for users.

CI/CD Automation

Automating your release process reduces errors and ensures consistent publishing. Here's a typical setup with Changesets and GitHub Actions.

.github/workflows/release.yml
name: Release

on:
  push:
    branches: [main]

permissions:
  contents: write
  pull-requests: write
  id-token: write  # For npm provenance

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v2
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm
          registry-url: https://registry.npmjs.org

      - run: pnpm install --frozen-lockfile
      - run: pnpm build
      - run: pnpm test

      - name: Create Release PR or Publish
        uses: changesets/action@v1
        with:
          publish: pnpm changeset publish
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

For improved security, use npm Trusted Publishing instead of storing tokens:

Using npm provenance (OIDC)
- name: Publish with provenance
  run: pnpm changeset publish --provenance
  env:
    NPM_CONFIG_PROVENANCE: true

Managing npm Notifications

Here's the problem nobody warns you about: npm sends a separate "Successfully published" email for every package you publish. Release 20 packages? That's 20 emails. Do daily releases? That's hundreds of emails per week.

@acme/core@2.0.0 published
@acme/utils@2.0.0 published
@acme/cli@2.0.0 published
@acme/config@2.0.0 published
... 16 more emails

npm has no setting to disable or batch these notifications. Your options:

Option 1: Filter in your email client

Set up a filter to archive or delete emails from support@npmjs.com with subject "Successfully published". See our guide to filtering npm emails.

Option 2: Get a digest instead

npmDigest consolidates your notifications into a single daily, weekly, or monthly email. All packages grouped by scope, with publishing metadata (OIDC, token, IP) included.

Start 14-day free trial

No credit card required. Only pay for months you actually use it.

Frequently asked questions

How do I publish all packages in a monorepo at once?
Use a monorepo tool like Lerna, Turborepo, or Changesets. These tools detect which packages have changed, bump versions appropriately, and publish them to npm in the correct order based on dependencies.
Should I use independent or fixed versioning?
Fixed versioning (all packages share the same version) is simpler but can lead to unnecessary version bumps. Independent versioning allows each package to evolve separately but requires more careful dependency management. Most teams start with fixed and move to independent as the monorepo matures.
How do I handle npm email notifications from monorepo publishes?
npm sends a separate email for every package published. For a 20-package monorepo, that's 20 emails per release. You can filter these emails in your email client, or use npmDigest to consolidate them into a single daily, weekly, or monthly digest.
What is npm Trusted Publishing?
Trusted Publishing (also called OIDC publishing) lets you publish packages from GitHub Actions or GitLab CI without storing npm tokens as secrets. The CI provider authenticates directly with npm, improving security and auditability.
How do I set up automated publishing from CI?
Configure your CI workflow to run on release tags or when changes are merged to main. Use npm Trusted Publishing for secure authentication, or store an npm automation token as a secret. Tools like Changesets have built-in GitHub Actions for this.

Related guides

How to Stop npm Email Notifications

Step-by-step filter instructions for Gmail, Outlook, Fastmail, and iCloud.