npm ci, pnpm, Yarn and Bun: reliable lockfile installs in CI
A clean CI runner should reproduce the dependency resolution you reviewed. Use the package manager and lockfile already chosen by your repository, and fail when they disagree with the manifests.
Choose the command for your package manager
Run one matching command at the install root after provisioning the repository's runtime and package-manager versions. These are alternatives, not steps to run together.
| Manager | Committed lockfile | CI command |
|---|---|---|
| npm | package-lock.json | npm ci |
| pnpm | pnpm-lock.yaml | pnpm install --frozen-lockfile |
| Yarn 2+ | yarn.lock | yarn install --immutable |
| Yarn Classic (1.x) | yarn.lock | yarn install --frozen-lockfile |
| Bun | bun.lock | bun install --frozen-lockfile |
npm ci removes an existing node_modules directory and refuses to rewrite a mismatched lockfile. pnpm's frozen mode also requires a lockfile. Modern Yarn's immutable mode checks whether installation would modify the lockfile; immutable-cache is a separate restriction and should not be added to a cold cache indiscriminately. Older Bun repositories may use bun.lockb; treat migration as a reviewed change.
When it works locally but fails in GitHub Actions
- Compare the runner's runtime and package-manager versions with the versions used to create the lockfile. A tool upgrade can change resolution or the supported lockfile format.
- Check that every changed package.json and the resulting lockfile were committed together. Reproduce the install in a clean checkout before editing the workflow.
- Confirm the working directory. A workspace application can own its build scripts while the repository root owns its shared lockfile.
- Compare project configuration and registry access. npm flags that affect the dependency tree must match those used when creating the lockfile. Missing private-registry credentials need a scoped credential fix.
- Review the reported failure. A manifest mismatch, network error, unsupported platform and rejected install script have different remedies.
If dependency changes are intentional, regenerate with the chosen manager locally, review the diff, and commit it. Removing the frozen flag just to make CI green lets the runner resolve dependencies that were not in the reviewed change.
A dependency cache is an optimization
Keep the immutable install step on cache hits. Include the relevant lockfile, package-manager version and platform in cache decisions, and check behavior with an empty cache. A cached dependency directory should not hide an incomplete manifest or make a failed install look successful.
Frozen resolution alone does not prove that dependencies are safe or builds are identical. Runtime versions, native dependencies, lifecycle scripts, environment inputs and network access still matter. Run the project's real lint, typecheck, test and build scripts after installation.
Connect installation to a reviewed pipeline
DeployLint inspects package-manager evidence and separates application roots from install roots before previewing a workflow. Ambiguous evidence needs resolution before generation. Confirm the supported deployment host and credentials independently of the install command.
Continue with the monorepo root guide and GitHub Actions setup checklist.
Scan your repository freeAssessment and preview are free. Opening setup and maintenance PRs requires an eligible plan.
Official references
Check the documentation matching your pinned version: npm ci, pnpm install, modern Yarn install, Yarn Classic install, and Bun install.