Every JavaScript project depends on a package manager to download libraries, lock their versions and run scripts. In 2026 there are four serious choices: npm, pnpm, Yarn and Bun. This guide explains what each one does differently, how to pin one per project, safe settings for CI and Docker, and how to move between them.
Use npm if you want the default that ships with Node.js and works everywhere, pnpm for monorepos and the smallest disk use, Yarn 4 if you want Plug'n'Play or already use it, and Bun for speed on new projects. Pick one per repository, commit its lockfile, pin the version with the packageManager field, and install in CI with the frozen-lockfile command (npm ci, pnpm install --frozen-lockfile, yarn install --immutable or bun install --frozen-lockfile).
1. What a package manager does
- Resolves versions. It reads the version ranges in
package.json, including your dependencies' own dependencies, and picks exact versions. - Writes a lockfile. The lockfile records those exact versions, so every machine installs the same tree. Commit it.
- Installs packages into
node_modules, or, with Yarn Plug'n'Play, into a cache that Node reads through a loader. - Runs scripts from
package.jsonand exposes package commands fromnode_modules/.bin. - Manages workspaces, several packages in one repository sharing one lockfile.
- Talks to a registry, the public npm registry or a private one, with authentication.
2. The four options at a glance
| Manager | Lockfile | Install model | Best for |
|---|---|---|---|
| npm | package-lock.json | Classic node_modules | The default for most projects and teams |
| pnpm | pnpm-lock.yaml | Hard links from a shared store, strict node_modules | Monorepos, CI speed, disk space |
| Yarn 4 (Berry) | yarn.lock | Plug'n'Play by default, or node_modules | Teams that want PnP, constraints and plugins |
| Bun | bun.lock | Classic node_modules | New projects that also use the Bun runtime |
Yarn 1 (Classic) still works but receives only critical fixes. Keep it for an old project if it works; start new projects on one of the four above. Bun switched from the binary bun.lockb to the text bun.lock in Bun 1.2; if you still have a bun.lockb, run bun install --save-text-lockfile once, commit the new bun.lock and delete the old file.
3. Ideas that apply to every manager
- Lockfile. One per repository, at the root. Never commit two (for example
package-lock.jsonandyarn.locktogether). - Hoisting. npm, Yarn 1 and Bun flatten dependencies into the top
node_modules, so your code can accidentally import a package you never declared. pnpm and Yarn PnP block that, which catches "phantom dependencies" early. - Peer dependencies. A plugin that needs React, for example, declares React as a peer. Mismatched peers cause install warnings or errors; fix the versions rather than forcing the install.
- Overrides. Force a version of a nested dependency, for example to take a security fix:
overridesin npm and Bun,pnpm.overridesor theoverrideskey inpnpm-workspace.yamlin pnpm, andresolutionsin Yarn. - Install scripts. Some packages run code when installed (
postinstall). This is the main route supply-chain attacks use; see section 8.
4. npm: the default
npm ships with Node.js, so there is nothing to install. It supports workspaces and overrides.
npm install # install and update the lockfile
npm ci # clean install from the lockfile only (CI)
npm run build -w apps/web # run a script in one workspace
npm run build --workspaces --if-present
npm outdated
npm audit{
"private": true,
"workspaces": ["apps/*", "packages/*"],
"engines": { "node": ">=22" },
"packageManager": "[email protected]",
"overrides": { "some-nested-lib": "2.4.1" }
}5. pnpm: fast and strict
pnpm keeps one copy of each package version in a global store and hard-links it into projects, which saves a lot of disk and time. Its strict node_modules shows missing dependencies immediately.
# pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"pnpm install
pnpm install --frozen-lockfile # CI
pnpm -r build # every workspace package
pnpm --filter @acme/api test # one package
pnpm approve-builds # choose which packages may run install scriptsFrom pnpm 10, dependencies' install scripts do not run unless you allow them, which is a useful security default. If a native package such as sharp or esbuild fails after installing, it probably needs your approval.
6. Yarn 4: Plug'n'Play and constraints
Modern Yarn is installed per project. By default it uses Plug'n'Play: no node_modules folder, faster installs and strict dependency checks. Tools that expect node_modules may need the fallback linker.
# .yarnrc.yml
nodeLinker: pnp # or node-modules for maximum compatibilityyarn install --immutable # CI
yarn workspaces foreach -A run build
yarn up some-lib # upgrade a dependency everywhereCommitting .yarn/cache ("zero-installs") lets CI skip the download entirely, at the cost of a larger repository.
7. Bun: speed first
Bun is a JavaScript runtime with a built-in package manager, test runner and bundler. bun install is very fast and works with ordinary package.json projects, even if you run the app on Node.js.
bun install
bun install --frozen-lockfile # CI
bun run buildTest your native modules and build tools before switching a large existing project.
8. Pin the tool and protect your supply chain
Pin the manager. The packageManager field in package.json names the manager and its exact version, for example "[email protected]" (use the version your team runs; pnpm --version prints it). It tells tools and teammates exactly what to use. Corepack reads it and downloads that version. Corepack is bundled with Node.js 24 and earlier; from Node.js 25 it is no longer bundled, so install it with npm install -g corepack or install the manager directly.
Pin Node.js. Use an active LTS release: Node.js 24, or 22 while it is still supported. Node.js 20 and older have reached end of life. Put the version in .nvmrc or .node-version and in engines; see working with Node.js versions using nvm.
Several popular npm packages were hijacked in 2025 and published with malware that ran on install. Commit your lockfile, install with the frozen-lockfile command, enable two-factor authentication on your registry account, use short-lived scoped tokens in CI, and prefer settings that block dependency install scripts (the pnpm 10 default, or npm ci --ignore-scripts where your project allows it). Newer pnpm and Yarn releases can also refuse package versions published in the last few days; check your version's documentation for its minimum-release-age setting.
9. CI and Docker recipes
GitHub Actions with pnpm:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 24
- run: corepack enable
- run: pnpm install --frozen-lockfile
- run: pnpm -r buildFor npm, drop corepack enable, add cache: npm to setup-node and run npm ci. For Yarn, keep corepack enable and run yarn install --immutable. Check the actions' pages for their current major versions.
A multi-stage Docker build with npm:
FROM node:24-slim AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build && npm prune --omit=dev
FROM node:24-slim
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app ./
USER node
CMD ["node", "dist/server.js"]Copy the lockfile before the source so Docker caches the install layer, and never copy node_modules from your computer into an image: native modules must be built for the image's operating system.
10. Migrating between managers
- Pick the target and delete the old lockfile and
node_modules.Keep the old lockfile in Git history in case you need to compare versions. - Convert version overrides.Yarn
resolutionsbecome npmoverrides, and so on. pnpm can import an existing lockfile withpnpm import. - Install and commit the new lockfile, then set
packageManagerinpackage.json. - Fix what strictness reveals.Moving to pnpm or Yarn PnP often exposes imports of undeclared packages; add them to
dependencies. - Update CI, Dockerfiles and documentationto the new install command, and remove the old manager's config files.
11. Running this on Domain India
- Shared hosting (cPanel and DirectAdmin). The panel's Node.js tool installs your dependencies with its Run NPM Install button, so npm is the manager to use there. When we checked on 23 September 2026, cPanel offered Node.js 20, 22 and 24; choose 22 or 24. Build on your own computer and upload the result, because large installs and builds can hit the account's memory limits. Jailed SSH is available on every shared hosting plan; it is off by default, so ask support to enable it. Tools available inside the jailed shell vary. See how to deploy a Node.js app on shared hosting.
- App Platform. Node.js apps are detected automatically from
package.json; for any other setup, including a specific package manager, provide a Dockerfile. See getting started with the App Platform. - VPS. A self-managed server where you install Node.js and any package manager yourself.
- 512 MB RAM per app
- 1 vCPU
- 5 GB NVMe SSD
- PostgreSQL Database
Frequently asked questions
Which JavaScript package manager should I use in 2026?
npm for most projects, because it ships with Node.js and every tool supports it. Choose pnpm for monorepos or when install speed and disk space matter, Yarn 4 if you want Plug'n'Play, and Bun for new projects that use the Bun runtime.
Should I commit node_modules to Git?
No. Commit only the lockfile (package-lock.json, pnpm-lock.yaml, yarn.lock or bun.lock) and let each machine install from it.
Can I use two package managers in one project?
Avoid it. Two lockfiles resolve different versions and cause bugs that appear on one machine only. Pick one, pin it with the packageManager field in package.json, and delete the other lockfile.
What is the difference between npm install and npm ci?
npm install can update the lockfile. npm ci deletes node_modules and installs exactly what the lockfile says, failing if package.json and the lockfile disagree, which is what you want in CI and Docker builds.
Is Yarn 1 still supported?
Yarn 1 (Classic) receives only critical fixes. Existing projects can keep using it, but new projects should use npm, pnpm, Yarn 4 or Bun.
Which Node.js version should I use?
An active LTS release: Node.js 24, or 22 while it is still supported. Node.js 20 and older have reached end of life and no longer receive security fixes.
Can I use pnpm or Yarn on Domain India shared hosting?
The control panel's Node.js tool installs dependencies with npm, so use npm there. For another package manager, use the App Platform with a Dockerfile, or a VPS where you install whatever you need.
Ready to deploy? Run a small app on shared hosting, deploy from Git on the App Platform, or take full control on a VPS.
Push your code, and we detect and build Node.js apps automatically, with SSL and a PostgreSQL database included.
See the App Platform