Converting from npm to Bun
January 13, 2025·3 min read
Complete guide to converting an npm-based project to Bun, including Docker, CI/CD, and deployment configurations.
Why Bun?
- 10-100x faster package installation than npm
- Drop-in replacement for Node.js - no code changes needed
- Built-in bundler and test runner
- Smaller Docker images when using Bun base image
Prerequisites
- Existing project using npm
- Admin/sudo access (for Bun installation)
Step 1: Install Bun
Windows (PowerShell)
irm bun.sh/install.ps1 | iexmacOS/Linux
curl -fsSL https://bun.sh/install | bashVerify installation:
bun --versionStep 2: Install Dependencies with Bun
In your project directory:
# Remove npm lock file (optional but recommended)
rm package-lock.json
# Install dependencies with Bun
bun installThis creates a bun.lock file (Bun's lockfile) and installs all packages from package.json.
Note: package.json stays the same - no changes needed!
Step 3: Test Your Build
Verify everything works:
bun run build
bun run dev
bun run testAll npm scripts work as-is with bun run.
Step 4: Update Dockerfile
If you use Docker, update your Dockerfile to use Bun:
Before (npm):
FROM node:20-slim AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run buildAfter (Bun):
FROM oven/bun:1 AS builder
WORKDIR /app
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile
COPY . .
RUN bun run buildKey changes:
- Base image:
oven/bun:1 - Copy
bun.lockinstead ofpackage-lock.json - Use
bun install --frozen-lockfile(likenpm ci)
Step 5: Update CI/CD Pipeline
GitHub Actions
Before:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm install
- name: Build
run: npm run buildAfter:
- name: Set up Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Build
run: bun run buildCloudflare Workers/Pages
No changes needed! Wrangler works with Bun out of the box.
Just update your npm scripts:
{
"scripts": {
"deploy": "bun run build && wrangler pages deploy public"
}
}Step 6: Update .gitignore
Add Bun-specific ignores:
# Dependencies
node_modules/
# Lock files (choose one approach)
# Option 1: Keep both for compatibility
package-lock.json
yarn.lock
# Option 2: Bun only (remove npm lock from git)
# package-lock.json committed previously will be ignoredNote: bun.lock should be committed to git (just like package-lock.json).
Common Commands
| npm | Bun | Description |
|---|---|---|
npm install |
bun install |
Install dependencies |
npm install <pkg> |
bun add <pkg> |
Add package |
npm install -D <pkg> |
bun add -d <pkg> |
Add dev dependency |
npm uninstall <pkg> |
bun remove <pkg> |
Remove package |
npm run <script> |
bun run <script> |
Run package.json script |
npx <command> |
bunx <command> |
Execute package binary |
npm ci |
bun install --frozen-lockfile |
Clean install |
Verification Checklist
After conversion, verify:
-
bun installcompletes successfully -
bun run buildworks -
bun run devstarts dev server - All tests pass with
bun run test - Docker build succeeds (if applicable)
- CI/CD pipeline passes
- Production deployment works
Troubleshooting
Peer Dependency Warnings
Bun may show peer dependency warnings. These are usually safe to ignore:
warn: incorrect peer dependency "[email protected]"Native Modules
Most native modules work. If you encounter issues:
bun install --forcePostinstall Scripts
Some packages have postinstall scripts. Check with:
bun pm untrustedRun blocked postinstall scripts:
bun pm trust <package-name>Performance Comparison
Real-world example (this blog):
| Operation | npm | Bun | Speedup |
|---|---|---|---|
| Fresh install | ~60s | ~5s | 12x faster |
| Install with cache | ~15s | ~2s | 7.5x faster |
| Gatsby build | ~210s | ~207s | Similar* |
| Dev server start | ~15s | ~12s | ~20% faster |
*Gatsby uses its own build system (Webpack), so build time is similar. Projects using Bun's native bundler see much bigger speedups (2-10x faster).
Rollback Plan
If you need to rollback:
- Restore
package-lock.jsonfrom git - Delete
bun.lock - Run
npm install - Revert Dockerfile and CI/CD changes
Additional Resources
Notes
- Bun is API-compatible with Node.js - no code changes needed
- Works with all major frameworks (Next.js, Gatsby, Vite, etc.)
- Can run
.js,.ts,.jsx,.tsxfiles directly - Not all npm packages are tested with Bun - check compatibility for critical dependencies