# Customer Worker bundle sizing This records the production `pnpm build && wrangler deploy --dry-run` measurement for the customer Worker. It distinguishes upload size from isolate-start evaluation: Wrangler currently folds dynamic imports into the one `index.js` Worker module, so a lazy dependency is still uploaded. ## 2026-09-12 baseline | Artifact | Raw bytes | gzip bytes | | ----------------------------------- | ---------: | ---------: | | `dist/server/entry.js` (Octane SSR) | 3,697,200 | 695,920 | | Wrangler `index.js` | 12,733,452 | 2,513,169 | The Octane entry is the largest independent server-side component. Removing it would change direct-navigation and hydration behavior covered by `test:app-shell` and `test:worker`, so it is not a lower-complexity sizing seam. ## Deferred Bash interpreter evaluation The customer `Conversation` explicitly sets `workspaceBash = false`; interactive shell work uses the native `@cloudflare/sandbox` path instead. Before this change, importing Think eagerly loaded `@cloudflare/think/dist/tools/workspace.js`, which statically loaded `just-bash`. `agents/skills` also statically loaded it even though it is needed only by a Skill declaring the Bash runtime. The package patches retain both APIs and load `just-bash` only in the two executable Bash paths: - `@cloudflare/think` `createBashTool(...).execute()` - `agents/skills` `runBashScript(...)` `tests/worker-bundle-boundaries.test.mjs` protects the deferred edges and exercises Think's Bash tool. The ordinary conversation and Skill runner tests remain the product-level coverage for the disabled-workspace and native Skill paths. | Wrangler `index.js` | Raw bytes | gzip bytes | Change from baseline | | ----------------------------------- | ---------: | ---------: | ------------------------: | | Baseline static imports | 12,733,452 | 2,513,169 | — | | Deferred interpreter initialization | 12,806,695 | 2,515,213 | +73,243 raw / +2,044 gzip | This is intentionally **not** an upload-size claim. The emitted module now has only two `init_browser()` calls, each behind the relevant `await import("just-bash")`; it no longer invokes the interpreter during Worker module evaluation. The small upload increase is Wrangler's inlined dynamic-import wrapper. ## Upstream opportunity To reduce both upload bytes and startup evaluation, Cloudflare's packages need a compile-time boundary rather than only an internal dynamic import: 1. Think's root entry imports `./tools/workspace.js`, which currently includes every default workspace tool. Publish a non-Bash workspace entrypoint and have a `workspaceBash: false` Think entry avoid the Bash executor entirely. 2. Split the `agents/skills` Bash runner from the metadata/registry entrypoint. Flarebot imports `fromManifest`, `SkillRegistry`, and parsing helpers, but not the Bash Skill runtime. 3. Preserve the existing `@cloudflare/sandbox` shell and `@cloudflare/think` APIs. The desired SDK change is an import boundary, not an application replacement or a minification change. With a Worker bundler that supports separate dynamic modules, the current deferred edges may become an upload saving automatically; remeasure before claiming it.