Summary
effect-tsgo patch --typescript modifies the installed TypeScript-Go binary in place. With Bun's global virtual store enabled, that binary is inside a shared cache, so patching one project changes the compiler used by other projects with the same dependency resolution.
The same applies to the Oxlint integration selected by effect-tsgo patch --oxlint.
Environment
- Bun 1.4.2
@effect/tsgo 0.45.0
- TypeScript 7.0.2
- macOS arm64
linker = "isolated"
globalStore = true
Reproduction
Create two projects with the same dependencies and point both at one Bun store:
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT
for project in a b; do
mkdir -p "$tmp/$project"
cat > "$tmp/$project/package.json" <<'JSON'
{"name":"tsgo-global-store-repro","private":true,"dependencies":{"@effect/tsgo":"0.45.0","typescript":"7.0.2"}}
JSON
cat > "$tmp/$project/bunfig.toml" <<'TOML'
[install]
linker = "isolated"
globalStore = true
hoist = false
TOML
(cd "$tmp/$project" && BUN_INSTALL="$tmp/bun" BUN_INSTALL_GLOBAL_STORE=1 bun install --ignore-scripts)
done
(cd "$tmp/a" && \
BUN_INSTALL="$tmp/bun" BUN_INSTALL_GLOBAL_STORE=1 \
node_modules/.bin/effect-tsgo patch --typescript)
realpath "$tmp/a/node_modules/.bun/@typescript+typescript-darwin-arm64@7.0.2/node_modules/@typescript/typescript-darwin-arm64/lib/tsc"
realpath "$tmp/b/node_modules/.bun/@typescript+typescript-darwin-arm64@7.0.2/node_modules/@typescript/typescript-darwin-arm64/lib/tsc"
Both paths resolve to the same file under BUN_INSTALL/install/cache/links/. The patch command creates the .original backup and replaces that shared file. Project b observes the patched binary even though it was never patched.
Expected behavior
Patching one project should not modify a package shared by other projects. The command could create a project-local copy or overlay, or refuse to patch a target outside the project with an actionable error.
BUN_INSTALL_GLOBAL_STORE=0 avoids the problem because the target package is materialized inside the project. That workaround removes the main storage benefit of Bun's global virtual store.
The current patcher performs the in-place rename and copy in _packages/tsgo/src/patcher/index.ts.
Summary
effect-tsgo patch --typescriptmodifies the installed TypeScript-Go binary in place. With Bun's global virtual store enabled, that binary is inside a shared cache, so patching one project changes the compiler used by other projects with the same dependency resolution.The same applies to the Oxlint integration selected by
effect-tsgo patch --oxlint.Environment
@effect/tsgo0.45.0linker = "isolated"globalStore = trueReproduction
Create two projects with the same dependencies and point both at one Bun store:
Both paths resolve to the same file under
BUN_INSTALL/install/cache/links/. The patch command creates the.originalbackup and replaces that shared file. Projectbobserves the patched binary even though it was never patched.Expected behavior
Patching one project should not modify a package shared by other projects. The command could create a project-local copy or overlay, or refuse to patch a target outside the project with an actionable error.
BUN_INSTALL_GLOBAL_STORE=0avoids the problem because the target package is materialized inside the project. That workaround removes the main storage benefit of Bun's global virtual store.The current patcher performs the in-place rename and copy in
_packages/tsgo/src/patcher/index.ts.