Files
stack/packages/mosaic/framework/skills/pnpm/references/best-practices-migration.md
T
fargo 1a822493ba format: apply repo prettier (3.8.1) to the folded skills tree
963 markdown files reformatted with the repository's pinned prettier so
pnpm format:check covers the folded tree like every other repo file.

The formatter's embedded-language pass also normalized code fences
(TS semicolons, closed HTML tags in examples, lowercased CSS hex colors,
one renumbered list that skipped an index). Alphanumeric token deltas vs
the fold commit were audited file-by-file; all are formatter-equivalent
markup normalizations plus the four sanitized skills.
2026-08-19 14:37:17 -05:00

5.0 KiB

name, description
name description
migration-to-pnpm Migrating from npm or Yarn to pnpm with minimal friction

Migration to pnpm

Guide for migrating existing projects from npm or Yarn to pnpm.

Quick Migration

From npm

# Remove npm lockfile and node_modules
rm -rf node_modules package-lock.json

# Install with pnpm
pnpm install

From Yarn

# Remove yarn lockfile and node_modules
rm -rf node_modules yarn.lock

# Install with pnpm
pnpm install

Import Existing Lockfile

pnpm can import existing lockfiles:

# Import from npm or yarn lockfile
pnpm import

# This creates pnpm-lock.yaml from:
# - package-lock.json (npm)
# - yarn.lock (yarn)
# - npm-shrinkwrap.json (npm)

Handling Common Issues

Phantom Dependencies

pnpm is strict about dependencies. If code imports a package not in package.json, it will fail.

Problem:

// Works with npm (hoisted), fails with pnpm
import lodash from 'lodash'; // Not in dependencies, installed by another package

Solution: Add missing dependencies explicitly:

pnpm add lodash

Missing Peer Dependencies

pnpm reports peer dependency issues by default.

Option 1: Let pnpm auto-install:

# .npmrc (default in pnpm v8+)
auto-install-peers=true

Option 2: Install manually:

pnpm add react react-dom

Option 3: Suppress warnings if acceptable:

{
  "pnpm": {
    "peerDependencyRules": {
      "ignoreMissing": ["react"]
    }
  }
}

Some tools don't work with symlinks. Use hoisted mode:

# .npmrc
node-linker=hoisted

Or hoist specific packages:

public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*babel*

Native Module Rebuilds

If native modules fail, try:

# Rebuild all native modules
pnpm rebuild

# Or reinstall
rm -rf node_modules
pnpm install

Monorepo Migration

From npm Workspaces

  1. Create pnpm-workspace.yaml:

    packages:
      - 'packages/*'
    
  2. Update internal dependencies to use workspace protocol:

    {
      "dependencies": {
        "@myorg/utils": "workspace:^"
      }
    }
    
  3. Install:

    rm -rf node_modules packages/*/node_modules package-lock.json
    pnpm install
    

From Yarn Workspaces

  1. Remove Yarn-specific files:

    rm yarn.lock .yarnrc.yml
    rm -rf .yarn
    
  2. Create pnpm-workspace.yaml matching workspaces in package.json:

    packages:
      - 'packages/*'
    
  3. Update package.json - remove Yarn workspace config if not needed:

    {
      // Remove "workspaces" field (optional, pnpm uses pnpm-workspace.yaml)
    }
    
  4. Convert workspace references:

    // From Yarn
    "@myorg/utils": "*"
    
    // To pnpm
    "@myorg/utils": "workspace:*"
    

From Lerna

pnpm can replace Lerna for most use cases:

# Lerna: run script in all packages
lerna run build

# pnpm equivalent
pnpm -r run build

# Lerna: run in specific package
lerna run build --scope=@myorg/app

# pnpm equivalent
pnpm --filter @myorg/app run build

# Lerna: publish
lerna publish

# pnpm: use changesets instead
pnpm add -Dw @changesets/cli
pnpm changeset
pnpm changeset version
pnpm publish -r

Configuration Migration

.npmrc Settings

Most npm/Yarn settings work in pnpm's .npmrc:

# Registry settings (same as npm)
registry=https://registry.npmjs.org/
@myorg:registry=https://npm.myorg.com/

# Auth tokens (same as npm)
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

# pnpm-specific additions
auto-install-peers=true
strict-peer-dependencies=false

Scripts Migration

Most scripts work unchanged. Update pnpm-specific patterns:

{
  "scripts": {
    // npm: recursive scripts
    "build:all": "npm run build --workspaces",
    // pnpm: use -r flag
    "build:all": "pnpm -r run build",

    // npm: run in specific workspace
    "dev:app": "npm run dev -w packages/app",
    // pnpm: use --filter
    "dev:app": "pnpm --filter @myorg/app run dev"
  }
}

CI/CD Migration

Update CI configuration:

# Before (npm)
- run: npm ci

# After (pnpm)
- uses: pnpm/action-setup@v4
- run: pnpm install --frozen-lockfile

Add to package.json for Corepack:

{
  "packageManager": "[email protected]"
}

Gradual Migration

For large projects, migrate gradually:

  1. Start with CI: Use pnpm in CI, keep npm/yarn locally
  2. Add pnpm-lock.yaml: Run pnpm import to create lockfile
  3. Test thoroughly: Ensure builds work with pnpm
  4. Update documentation: Update README, CONTRIBUTING
  5. Remove old files: Delete old lockfiles after team adoption

Rollback Plan

If migration causes issues:

# Remove pnpm files
rm -rf node_modules pnpm-lock.yaml pnpm-workspace.yaml

# Restore npm
npm install

# Or restore Yarn
yarn install

Keep old lockfile in git history for easy rollback.