Originally published on 2026-01-15
Original article (Japanese): Bunは速い、pnpmは正しい:2つのパッケージマネージャが示すJSエコシステムの未来
When considering a transition from npm or Yarn, two options that inevitably come up are pnpm and Bun. Both claim to be "faster than npm," but what are the actual differences?
According to the State of JS 2024, pnpm has a high "retention" rate and stable ratings from developers. Meanwhile, Bun is also gaining traction as a new option. However, the design philosophies of the two are quite contrasting. pnpm focuses on "correct dependency management," while Bun pursues "speed and developer experience (DX)." In this article, we will clarify the differences between these two package managers and provide hints for finding the right choice for your project.
What Were the Issues with npm?
Before considering a transition, let's first outline the challenges that npm faces.
1. Slow Installation Speed
According to official benchmarks (as of January 2026), the speed of clean installs is as follows:
| Package Manager | Time |
|---|---|
| npm | 34.1s |
| pnpm | 8.5s (4x faster) |
| Yarn Classic | 7.2s |
| Yarn PnP | 3.5s |
Considering not only the waiting time for npm install during local development but also the cumulative time in CI/CD pipelines, this difference is significant.
2. Waste of Disk Space
npm copies packages into node_modules for each project, leading to duplication of the same packages across multiple projects. If you have 10 projects with the same dependencies, you end up consuming 10 times the disk space.
3. Phantom Dependencies
In npm's flat node_modules structure, dependencies that are not explicitly listed in package.json can still be accessed via require(). This creates "phantom dependencies" that are not documented in package.json, undermining the portability of the project.
The Philosophy of pnpm: Correctness and Robustness
pnpm (performant npm) is a package manager that aims to solve npm's problems in a "correct way."
Content-Addressable Store
The most significant feature of pnpm is its use of a global Content-Addressable Store. All packages are stored on disk only once and referenced via hard links from each project's node_modules.
# Even if the same package is used in multiple projects
# Disk usage is only for one instance
~/.pnpm-store/
├── react@18.2.0/
└── lodash@4.17.21/
# Each project references via hard links
project-a/node_modules/react → ~/.pnpm-store/react@18.2.0/
project-b/node_modules/react → ~/.pnpm-store/react@18.2.0/
This significantly reduces disk usage as the number of projects increases.
The location of the store varies by environment, and you can check it with pnpm store path.
Strict Dependency Management
pnpm creates a symbolic link structure within node_modules, making only the dependencies listed in package.json accessible.
node_modules/
├── .pnpm/ # Actual packages are here
│ ├── react@18.2.0/
│ └── lodash@4.17.21/
├── react -> .pnpm/react@18.2.0/node_modules/react
└── (lodash is inaccessible)
This mechanism technically prevents Phantom Dependencies. If code that worked in npm breaks in pnpm, it simply reveals a latent bug.
Realities Faced During Transition
The most common issue when transitioning to pnpm is precisely this "correctness." Code like the following may stop working:
// Only "react" is listed in package.json
// But lodash is a dependency of react, so it works in npm
import _ from 'lodash'; // ❌ Error in pnpm
The fix is straightforward:
# Explicitly add if truly needed
pnpm add lodash
This "breaking" experience is a good opportunity to diagnose the health of your project. There are reports in Reddit threads stating, "It took 4 days, but it was 100% worth it."
The Philosophy of Bun: Speed and DX
Bun is an "all-in-one JavaScript runtime" that goes beyond just being a package manager.
Speed Written in Zig
Bun is implemented in the Zig language and integrates not just a package manager, but also a JavaScript runtime, test runner, and bundler.
# As a package manager
bun install # Incredibly faster than npm install
# As a runtime
bun run app.ts # Faster than Node.js/ts-node
# As a test runner
bun test # Faster than Jest
# As a bundler
bun build app.ts # Faster than webpack/esbuild
Since everything is integrated, there is no cost of switching tools, providing a consistent developer experience (DX).
Speed-Focused Architecture
Bun's installation speed is astonishing. Official benchmarks show it surpassing pnpm and Yarn. However, this is due to a different approach than the traditional Content-Addressable Store.
Compatibility Challenges
Bun's biggest challenge is compatibility with the Node.js ecosystem. Issues may arise with native modules (.node files) and certain APIs.
# Example: Packages that depend on node-gyp
bun install bcrypt # May not work
The official stance is to aim for "100% compatibility," but in real projects, some differences can be critical.
Which One Should You Choose? A Guide Based on Project Characteristics
When to Choose pnpm
pnpm is ideal if you meet the following conditions:
- Large Projects / Monorepos: You want to strictly manage dependencies across multiple packages.
- Concerned About CI/CD Costs: You want to reduce charges on platforms like GitHub Actions.
- Long-Term Operations: You prioritize the health of dependencies.
- Transitioning from npm: You want high compatibility and a gradual migration.
Especially in monorepo setups using Turborepo or Nx, pnpm workspaces have become standard.
# pnpm-workspace.yaml
packages:
- 'apps/*'
- 'packages/*'
When to Choose Bun
Bun is optimal if you meet the following conditions:
- New Projects: You have a greenfield project with few compatibility issues.
- Speed is Paramount: You prioritize accelerating the development cycle.
- Primarily Using TypeScript: You have little dependency on native modules.
- Experimental Projects: You want to keep up with the latest technologies.
Especially in personal projects or the early stages of startups, Bun's integration and speed can significantly enhance development efficiency.
Reasons to Try Both
In fact, pnpm and Bun are not mutually exclusive. You can use them in the following way:
# Use Bun for fast local development
bun install
bun run dev
# Use pnpm for stability in CI (Docker caching works well)
pnpm install --frozen-lockfile
pnpm test
The Transition in Practice: Four Steps
1. Preparation (npm → pnpm/Bun)
# Remove existing node_modules
rm -rf node_modules
# For pnpm
npm install -g pnpm
pnpm import # Generate pnpm-lock.yaml from package-lock.json (keep package-lock.json)
rm -f package-lock.json
pnpm install
# For Bun
curl -fsSL https://bun.sh/install | bash
bun install
2. Compatibility Check
# Run tests to detect issues
pnpm test # or bun test
# Check the build
pnpm build # or bun run build
3. Fixing Phantom Dependencies (for pnpm)
Explicitly add any packages that cause errors:
# Example error:
# Error: Cannot find module 'lodash'
pnpm add lodash
4. Update CI/CD
# Example for GitHub Actions (pnpm)
- uses: pnpm/action-setup@v2
with:
version: 8
- run: pnpm install --frozen-lockfile
- run: pnpm test
# Example for GitHub Actions (Bun)
- uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- run: bun install --frozen-lockfile
- run: bun test
Conclusion: Philosophical Differences Determine Your Choice
Both pnpm and Bun share the commonality of being "faster than npm," but their underlying philosophies are vastly different.
pnpm pursues correctness and robustness. It prevents Phantom Dependencies, improves disk efficiency, and ensures the long-term health of projects. The "breaking" during migration is an opportunity to uncover hidden issues in your project.
Bun pursues speed and DX. It integrates a package manager, runtime, test runner, and bundler to provide a consistent high-speed experience. It shines in new projects and experimental development.
The choice between the two depends on your project's priorities. For large-scale, long-term operations, choose pnpm; for speed and innovation, opt for Bun. Fortunately, both have low migration costs, allowing you to experiment easily.
If you're tired of the node_modules hell of npm, consider trying one of them in a small project first. That experience will likely inform your choice for your next project.
Top comments (0)