Packages and scripts

Install and lock dependencies

Install a project's npm dependencies with Bun and use bun.lock for repeatable team and deployment installs.

Bun is also a package manager. It reads the same package.json file used by npm, so nothing about your project has to change.

Install the dependencies the project declares:

bun install

Bun prints a short summary at the end, something like 12 packages installed [340.00ms]. It’s fast, and you’ll notice that the first time you run it on a project you used to install with npm.

The command creates two important things:

  • node_modules, containing the packages the project uses
  • bun.lock, recording the exact version Bun resolved for every package

The lockfile is the part people skip over, so let’s be clear about what it’s for. Your package.json says "zod": "^4.1.0", which means “any 4.x release from 4.1.0 up”. That’s a range. bun.lock says which exact version was picked, say 4.1.3, plus the exact versions of everything that package depends on.

Commit bun.lock to Git. Without it, the same package.json can resolve to newer packages on a teammate’s machine next week, and now you’re debugging a difference nobody chose.

Use the lockfile in automation

During ordinary development, bun install may update bun.lock when package.json changes. That’s fine on your laptop.

In CI and deployments you want the opposite. Use a frozen install:

bun install --frozen-lockfile

This command refuses to change the lockfile. If package.json and bun.lock disagree, it stops with:

error: lockfile had changes, but lockfile is frozen

That failure is useful. It tells you someone edited the dependencies without recording a new resolution. The fix is to run a plain bun install locally, check the lockfile diff, and commit it.

For a production-only install, skip the development dependencies too:

bun install --frozen-lockfile --production

Moving an existing project to Bun

When a project has no bun.lock, Bun can migrate package-lock.json, yarn.lock, or pnpm-lock.yaml. Run bun install and it reads the old lockfile to resolve the same versions, then writes bun.lock. It leaves the old file in place.

Do not delete the old file right away. First install, run the tests, and verify the application under Bun. Then pick one package manager for the project and remove the extra lockfile in its own commit.

Two active lockfiles create ambiguity. A teammate should never have to guess which dependency graph is the real one.

Lesson completed