Convert a project from npm to pnpm package management. Use when switching package managers, setting up pnpm, or when user mentions migrating from npm to pnpm.
Convert a project from npm to pnpm for package management.
Analyze project structure:
Clean existing npm artifacts:
rm -rf node_modules
rm -f package-lock.json
Configure pnpm workspace (monorepos only):
pnpm-workspace.yaml:
packages:
- 'packages/*'
- 'apps/*'
Add packageManager field to package.json before dependencies:
"packageManager": "[email protected]"
pnpm info pnpm to identify the latest version and use that version in the packageManager field.Install dependencies with pnpm:
pnpm install
pnpm approve-builds. Never run this command - ignore the warning.Append pnpm-lock.yaml to .prettierignore (if using Prettier):
pnpm-lock.yaml to .prettierignore next to other package-related entries (package-lock.json, package.json)Move prisma to dependencies (if using Prisma):
prisma from devDependencies to dependencies in package.jsonHandle MSW (if using Mock Service Worker):
msw section from package.json (e.g., "msw": { "workerDirectory": "public" })"scripts": {
"postinstall": "msw init ./public --no-save || true",
...
}
Update package.json scripts:
npm run with pnpm (shorthand) in scripts that call other scriptspnpm exec:
npx prisma generate → pnpm exec prisma generatepnpm dlx:
npx create-react-app → pnpm dlx create-react-appUpdate playwright.config.ts (if using Playwright):
webServer.command to use pnpm instead of npm runwebServer: {
command: process.env.CI
? `cross-env PORT=${PORT} pnpm start`
: `cross-env PORT=${PORT} pnpm dev`,
},
.github/workflows/
- name: 📦 Install pnpm
uses: pnpm/action-setup@v4
- name: ΓÄö Setup node
uses: actions/setup-node@v4
with:
cache: pnpm
node-version-file: '.nvmrc'
- name: 📥 Install deps
run: pnpm install
- name: 🔬 Generate Prisma client
run: pnpm exec prisma generate
- name: 🔎 Type check
run: pnpm typecheck
npm run X with pnpm Xnpm to pnpmpnpm install automatically uses --frozen-lockfile in CI environmentsRUN npm install -g [email protected]pnpm install --frozen-lockfile for reproducible buildspnpm install --frozen-lockfile --prod for production-only depspnpm exec prisma generate (pnpm requires it)FROM node:24-slim AS base
ENV NODE_ENV="production"
# install pnpm
RUN npm install -g [email protected]
FROM base AS deps
COPY package.json pnpm-lock.yaml .npmrc ./
RUN pnpm install --frozen-lockfile
FROM base AS prod-deps
COPY package.json pnpm-lock.yaml .npmrc ./
RUN pnpm install --frozen-lockfile --prod
FROM base AS build
COPY --from=deps /app/node_modules node_modules
COPY package.json package.json
COPY prisma prisma
RUN pnpm exec prisma generate
COPY . .
RUN pnpm build
start.sh, entrypoint.sh, etc.npm run with pnpmnpx with pnpm exec# Before
npx prisma migrate deploy
npm run start
# After
pnpm exec prisma migrate deploy
pnpm start
"customManagers": [
{
"customType": "regex",
"managerFilePatterns": ["Dockerfile", "Dockerfile.*"],
"matchStrings": ["npm install -g pnpm@(?<currentValue>[^\\s]+)"],
"depNameTemplate": "pnpm",
"datasourceTemplate": "npm"
}
],
"packageRules": [
npm install → pnpm installnpm run dev → pnpm devnpm test → pnpm testpnpm install (should use lockfile)pnpm buildpnpm testpnpm devpnpm lint| npm | pnpm |
|---|---|
npm install | pnpm install |
npm install <pkg> | pnpm add <pkg> |
npm install -D <pkg> | pnpm add -D <pkg> |
npm install -g <pkg> | pnpm add -g <pkg> |
npm uninstall <pkg> | pnpm remove <pkg> |
npm run <script> | pnpm <script> or pnpm run <script> |
npm ci | pnpm install --frozen-lockfile |
npx <installed-pkg> | pnpm exec <pkg> |
npx <one-off-pkg> | pnpm dlx <pkg> |
npm update | pnpm update |
npm audit | pnpm audit |
pnpm-workspace.yaml for workspace config (not package.json workspaces)pnpm --filter <pkg-name> <cmd>pnpm -r <cmd>pnpm add <pkg> --filter <workspace>