Skip to content

bun install ignores --no-env-file, --env-file, and bunfig env = false #31450

Description

@jakequade-pc

What version of Bun is running?

1.3.14+0d9b296af (also reproduces on 1.3.1+89fa0f343).

The relevant code path on main is unchanged: src/install/PackageManager.zig:794.

What platform is your computer?

Darwin 25.1.0 arm64 arm

What steps can reproduce the bug?

mkdir /tmp/bun-envleak-repro && cd /tmp/bun-envleak-repro
cat > package.json <<'EOF'
{
  "name": "bun-envleak-repro",
  "version": "0.0.0",
  "scripts": {
    "postinstall": "node -e \"console.log('postinstall sees SOME_API_SECRET =', JSON.stringify(process.env.SOME_API_SECRET))\""
  }
}
EOF
echo 'SOME_API_SECRET=leaked-prod-value' > .env.production

bun install                          # postinstall sees "leaked-prod-value"
bun install --no-env-file            # postinstall sees "leaked-prod-value"  ❌
bun install --env-file=/dev/null     # postinstall sees "leaked-prod-value"  ❌
NODE_ENV=development bun install     # postinstall sees "leaked-prod-value"  ❌
bun install --production             # postinstall sees "leaked-prod-value"  ❌
echo 'env = false' > bunfig.toml && bun install   # postinstall sees "leaked-prod-value"  ❌

Knob matrix (all run against bun 1.3.14):

Knob Suppresses default .env* load at install?
bun install --no-env-file no
bun install --env-file=/dev/null no
bun install --production / -p / --omit=dev no
NODE_ENV=development bun install no
BUN_INSTALL_NODE_ENV=development bun install no
bunfig.toml env = false no
bunfig.toml [install] env = false no
Rename file outside {.env, .env.production, .env.local} yes (workaround)

What is the expected behavior?

bun install should honour the three knobs that PR #24767 added for the runtime / bundler:

  1. --no-env-file → skip default .env* loading.
  2. --env-file <path> → use only the explicit file(s).
  3. bunfig.toml env = false (or env.file = false / null) → skip default .env* loading.

bun --help advertises --env-file and --no-env-file as global flags, but bun install --help doesn't mention them and install silently ignores them — no error, no warning, no effect.

What do you see instead?

Install always loads .env.production, .env.local, and .env regardless of every documented knob. The matching code on main is:

// src/install/PackageManager.zig:794
try env.loadProcess();
try env.load(entries_option.entries, &[_][]u8{}, .production, false);

Three hardcodes:

The Loader.load(...) API (src/dotenv/env_loader.zig:600) already accepts the right parameters. PR #24767 already added disable_default_env_files to api.TransformOptions (src/api/schema.zig) and the bunfig parser (src/bunfig.zig). The install path just never reads them.

Additional information

Why this matters

Every dependency's postinstall script runs with process.env populated by the loaded .env* files. Anyone keeping app secrets in .env.production and running bun install in CI is silently handing those secrets to every transitive trustedDependencies postinstall — meaningfully worse than the runtime case PR #24767 already fixed, because postinstall is 3rd-party code.

I have hit this on my own React Native / Expo app. I worked around it by renaming .env.production.env.prod so the loader's hardcoded match misses, but that's a name-collision workaround, not a fix.

Suggested scope

Strictly mirror PR #24767's pattern for install:

  • Wire ctx.args.env_files and ctx.args.disable_default_env_files into the env.load(...) call at PackageManager.zig:794.
  • Register --env-file / --no-env-file on bun install's clap params if install uses its own parser (otherwise the global ones should flow through via ctx.args).
  • Add test/cli/install/no-env-file.test.ts mirroring test/cli/run/no-envfile.test.ts.

Happy to open the PR if maintainers are receptive. Would also like to know if there's appetite for a separate discussion on whether bun install should auto-load .env* at all by default — security argument above, but that's a default-behaviour change.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions