You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
compile: prune modules reachable only through unused re-exports of side-effect-free packages (Bun's graph: 4,063 modules; perry compiles and initializes 7,897 for the same OpenCode entry) #10180
For the same entry (packages/opencode/src/index.ts, OpenCode v1.18.30, bun condition) Bun's bundler graph has 4,063 modules; perry compile --platform bun collects and compiles 7,897 (audit: 2,067 first-party, 5,830 from 422 packages). The native binary then runs every one of those module initializers before main parses argv, which is most of the 2.0 s user CPU of opencode --version (bun: 0.4 s), and every module is ~130 KB of .text on average in the 1.05 GB binary.
Where the extra modules come from (from perry-cache/audit.json vs Bun's metafile, both saved under secret-tests/opencode-1.18.30-inventory/):
Bun drops modules that are only reached through unused re-exports of side-effect-free packages ("sideEffects": false / pure barrels): remeda 24 modules in Bun vs 170 in perry, effect 225 vs 294, openai 145 vs 152, ai (227 in perry) similarly; barrel index.ts files that export * from "./x" pull in every sibling even when the importer names one symbol.
31 packages are present in several versions; @ai-sdk/provider-utils in 11 versions = 1,012 modules, @ai-sdk/provider 6 versions = 648, zod 3 versions = 189, semver 3, @ai-sdk/openai 3, entities 3. Bun's graph has 3 provider-utils versions. Perry follows each provider package's nested copy; that is correct resolution, but most of those copies are reached only through barrels of providers that OpenCode loads lazily via import() (BUNDLED_PROVIDERS in src/provider/provider.ts:113).
node/bun condition twins are only 6 files, negligible.
Ask
Collection-time pruning that matches the bundler's semantics without changing program behaviour:
For packages that declare "sideEffects": false (or whose modules have no top-level effects by analysis), do not compile or initialize modules that are reached only through export { x } from / export * from re-exports whose bindings the importer never uses (bundler-style live-binding tree shaking at the module level; the module stays available for dynamic import).
Keep dynamic-import-only subgraphs out of the eager init order and out of the eager .text if possible (verify with the OpenCode graph that prettier/typescript/babel are not initialized on --version).
Report the pruned count in the compile summary (Found N module(s): …, M pruned as unreferenced side-effect-free re-exports).
Acceptance
OpenCode v1.18.30 collects within ~10 % of Bun's 4,063 modules; opencode --version user CPU and binary .text reported before/after.
A fixture with a sideEffects: false barrel proves the unused sibling is neither compiled nor initialized, and that a sibling with a top-level side effect (or a package without the flag) is still initialized in ESM order.
Collection falls from 7,897 to 7,068 modules (829 / 10.5% removed); eager modules fall from 2,433 to 2,376. The 43 source-graph tests pass. This remains above the requested Bun-relative target.
The one full compile completed all 7,068 modules but failed at linking Babel transformAsync from OpenTUI Solid. A minimal CommonJS getter-forwarding fixture reproduces the same missing symbol on pristine bb9aa5a, pruning disabled, and pruning enabled. No CLI ladder or after CPU/size result is available. The PR includes the safety rule, package counts, test evidence, exact commands, and the blocker reproducer; generated objects are retained in the lane cache. Refs #10107.
Activity
proggeramlug commentedon Sep 14, 2026
PR: #10245
Collection falls from 7,897 to 7,068 modules (829 / 10.5% removed); eager modules fall from 2,433 to 2,376. The 43 source-graph tests pass. This remains above the requested Bun-relative target.
The one full compile completed all 7,068 modules but failed at linking Babel
transformAsyncfrom OpenTUI Solid. A minimal CommonJS getter-forwarding fixture reproduces the same missing symbol on pristine bb9aa5a, pruning disabled, and pruning enabled. No CLI ladder or after CPU/size result is available. The PR includes the safety rule, package counts, test evidence, exact commands, and the blocker reproducer; generated objects are retained in the lane cache. Refs #10107.compile: prune unused re-export subgraphs (#10180)