Skip to content

chore: migrate package management from pnpm/Corepack to npm #180

Description

@norberia

Background

Fulling currently pins pnpm@10.20.0 and invokes it through Corepack. For the current single-package Next.js application, this additional package-manager bootstrap is spread across:

  • package.json: packageManager, engines.pnpm, and pnpm.overrides
  • Dockerfile: two corepack enable / prepare sequences
  • GitHub Actions: pnpm/action-setup and PNPM_VERSION
  • README.md, CONTRIBUTING.md, and AGENTS.md: every command uses corepack pnpm ...
  • pnpm-lock.yaml

The project is not currently a workspace or monorepo and does not use pnpm-specific features such as catalogs, patches, or filters.

Decision

Migrate to npm and keep Node.js as the only runtime.

The goal is not to optimize for the fastest possible dependency installation. It is to reduce toolchain complexity across contributor onboarding, local development, CI, and container builds:

  1. npm is installed with Node.js, so contributors do not need to install or activate an additional package manager.
  2. Corepack is still marked Experimental and is no longer distributed with Node.js starting in Node.js 25. Continuing to make it the default entry point creates future upgrade work.
  3. npm ci fails when the lockfile and package.json are out of sync, which meets our reproducible-install requirements for CI and containers.
  4. npm supports root-level overrides, so the current pnpm.overrides configuration can be migrated directly.
  5. npm supports workspaces, so a future move to a monorepo would not immediately invalidate this decision.
  6. Next.js officially supports npm, pnpm, Yarn, and Bun; the framework does not require pnpm.

Alternatives considered

Option Assessment
Keep pnpm but remove Corepack Viable, but pnpm would still need to be installed and versioned separately. This removes Corepack without simplifying the overall bootstrap.
Yarn Not recommended. Yarn's official installation flow still starts with installing Corepack, so it does not address the underlying concern.
Bun Not recommended for now. Its installation speed and automatic pnpm lockfile migration are attractive, but it still introduces another executable that must be installed and pinned. Its dependency lifecycle-script behavior also differs from npm and pnpm, requiring additional validation for Prisma, Next.js native dependencies, and Playwright. The current project size does not justify that maintenance cost.
npm Recommended. It may not offer the fastest installs, but it provides the lowest toolchain and onboarding cost for the current single-package application.

Migration scope

  • Move pnpm.overrides to root-level overrides
  • Remove packageManager: pnpm@... and engines.pnpm; document the supported Node.js/npm version policy
  • Generate and commit package-lock.json, then remove pnpm-lock.yaml
  • Update GitHub Actions:
    • Remove pnpm/action-setup and PNPM_VERSION
    • Change the actions/setup-node cache to npm
    • Use npm ci, npm run ..., and npm exec ...
  • Update the Dockerfile:
    • Remove all Corepack installation and activation steps
    • Install dependencies with npm ci --ignore-scripts
    • Run Prisma generation and the application build through npm scripts or npm exec
  • Update prerequisites and commands in README.md, CONTRIBUTING.md, and AGENTS.md
  • Ensure the repository contains exactly one lockfile

Acceptance criteria

  • A clean environment with only a supported Node.js installation can run npm ci
  • npm run lint passes
  • npm test passes
  • npm run test:e2e passes
  • npm run build passes
  • The Docker image builds and starts successfully
  • CI no longer installs pnpm or Corepack
  • Lockfile dependency changes are reviewed during migration to avoid bundling unrelated dependency upgrades

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions