cloudflare / cloudflare/workers-sdk

@cloudflare/vite-plugin - WASM files incorrectly bundled into server assets with TanStack Start + Cloudflare Workers

Open
#14,972 4 comments 0 reactions 0 assignees View on GitHub
package:vite-plugin
Dominant language
TypeScript
Stars
4.5k
Forks
1.5k
Avg merge
3d 8h
Merged PRs (30d)
187

Description

### What versions & operating system are you using?

System:
OS: Windows 11 10.0.26200
CPU: (12) x64 AMD Ryzen 5 5500U with Radeon Graphics
Memory: 4.41 GB / 15.34 GB
Binaries:
Node: 26.5.1 - C:\Program Files\nodejs\node.EXE
npm: 11.12.1 - C:\Program Files\nodejs\npm.CMD
bun: 1.3.14 - C:\Users\Probi\.bun\bin\bun.EXE
npmPackages:
@cloudflare/vite-plugin: ^1.50.0 => 1.50.0
wrangler: ^4.118.0 => 4.118.0

### Please provide a link to a minimal reproduction

https://github.com/probir-sarkar/browserstay/tree/issue/jsquash

### Describe the Bug

```
bun run build
ls dist/client/assets/*.wasm # expected
ls dist/server/assets/*.wasm # BUG: identical files present
```

TanStack Start (SSR) copies Web Worker WASM binaries into dist/server/assets, inflating the worker bundle with ~9 MB of dead code — wasm should only ship in the client build.

When building a TanStack Start app that uses a Web Worker which imports @jsquash/* image codecs (which ship Emscripten-compiled .wasm files), the SSR/server build also emits all the WASM binaries plus the full worker chunk into dist/server/assets/.

The new URL(..., import.meta.url) worker pattern is resolved by Vite into every environment's module graph (both the client and ssr environments). TanStack Start's SSR build therefore bundles image.worker.ts and its @jsquash/* imports, emitting the worker chunk + WASM assets into dist/server/assets/.

Notably, clawpdf (which also ships a large pdfium.esm.wasm) does not leak — because it is imported via the client-only clawpdf/browser entry, so the server never pulls its worker/wasm graph. The leak is specific to code that is reachable from the SSR graph even though it only ever executes in a browser worker.

As a control, the **same app** (same routes, same `image.worker.ts`, same `@jsquash/*` imports) built with **Nitro** (via `@tanstack/react-start`'s Nitro adapter) does **not** leak WASM into the server output:

### Please provide any relevant error logs

$ bun run build
$ vite build && tsc --noEmit
(node:13632) [DEP0205] DeprecationWarning: `module.register()` is deprecated. Use `module.registerHooks()` instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
vite v8.2.0 building client environment for production...
[plugin rolldown:vite-resolve] Module "node:zlib" has been externalized for browser compatibility, imported by "D:/toolbox/node_modules/clawpdf/dist/png.js". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
[plugin rolldown:vite-resolve] Module "node:fs/promises" has been externalized for browser compatibility, imported by "D:/toolbox/node_modules/clawpdf/dist/input.js". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
[plugin rolldown:vite-resolve] Module "node:url" has been externalized for browser compatibility, imported by "D:/toolbox/node_modules/clawpdf/dist/input.js". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
[plugin rolldown:vite-resolve] Module "module" has been externalized for browser compatibility, imported by "D:/toolbox/node_modules/clawpdf/dist/vendor/pdfium.esm.js". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
✓ 2916 modules transformed.
computing gzip size...
dist/client/.assetsignore 0.02 kB
dist/client/assets/avif_enc_mt.worker-BSwsqSX3.js 28.17 kB
dist/client/assets/webp_dec-C990n7mh.wasm 137.96 kB │ gzip: 50.00 kB
dist/client/assets/mozjpeg_dec-muSO2n8T.wasm 166.47 kB │ gzip: 64.57 kB
dist/client/assets/image.worker-DDVYh5u9.js 174.50 kB
dist/client/assets/squoosh_png_bg-DAY7U9NW.wasm 181.08 kB │ gzip: 85.73 kB
dist/client/assets/mozjpeg_enc-DO-zoExo.wasm 251.52 kB │ gzip: 60.44 kB
dist/client/assets/webp_enc-BpZvKflB.wasm 281.26 kB │ gzip: 115.98 kB
dist/client/assets/webp_enc_simd-CFvKQ_80.wasm 345.58 kB │ gzip: 128.61 kB
dist/client/assets/avif_dec-B7YOdlSS.wasm 1,170.93 kB │ gzip: 344.65 kB
dist/client/assets/avif_enc-Co4TcJko.wasm 3,485.87 kB │ gzip: 1,136.17 kB
dist/client/assets/avif_enc_mt-DFoVXd45.wasm 3,534.66 kB │ gzip: 1,150.16 kB
dist/client/assets/pdfium.esm-CbcxY23o.wasm 3,984.25 kB │ gzip: 2,037.38 kB
dist/client/assets/globals-DD8m-uJz.css 133.07 kB │ gzip: 19.66 kB
dist/client/assets/owner-NnnQFEU-.js 0.06 kB │ gzip: 0.07 kB
dist/client/assets/__vite-browser-external-2W3EstLn.js 0.10 kB │ gzip: 0.11 kB
dist/client/assets/isElementDisabled-KSuuBj8D.js 0.11 kB │ gzip: 0.11 kB
dist/client/assets/loader-circle-CFsmICVq.js 0.13 kB │ gzip: 0.14 kB
dist/client/assets/serializeValue-B_EucO5O.js 0.13 kB │ gzip: 0.12 kB
dist/client/assets/upload-WXTY7sBC.js 0.21 kB │ gzip: 0.18 kB
dist/client/assets/services-BXJRwWis.js 0.22 kB │ gzip: 0.18 kB
dist/client/assets/circle-alert--pPuBEdh.js 0.23 kB │ gzip: 0.17 kB
dist/client/assets/typeof-B5XbjTb1.js 0.27 kB │ gzip: 0.16 kB
dist/client/assets/refresh-cw-B8oFrnvQ.js 0.30 kB │ gzip: 0.21 kB
dist/client/assets/mail-Be0RXyIx.js 0.31 kB │ gzip: 0.24 kB
dist/client/assets/trash-2-BjOoI-HM.js 0.31 kB │ gzip: 0.20 kB
dist/client/assets/file-text-DhezXSxX.js 0.37 kB │ gzip: 0.24 kB
dist/client/assets/hammer-CI3f9uwG.js 0.38 kB │ gzip: 0.26 kB
dist/client/assets/shadowDom-6ckEgmCV.js 0.40 kB │ gzip: 0.26 kB
dist/client/assets/zip-nwiPIsHA.js 0.55 kB │ gzip: 0.34 kB
dist/client/assets/useAriaLabelledBy-Cy8K8d1z.js 0.57 kB │ gzip: 0.38 kB
dist/client/assets/rolldown-runtime-hePW80VL.js 0.71 kB │ gzip: 0.42 kB
dist/client/assets/CSPContext-BdFjUw3J.js 0.97 kB │ gzip: 0.57 kB
dist/client/assets/badge-Bz0G4vqP.js 1.40 kB │ gzip: 0.64 kB
dist/client/assets/trust-bar-TLaKthze.js 1.45 kB │ gzip: 0.78 kB
dist/client/assets/with-selector-BM4Rcpsn.js 1.67 kB │ gzip: 0.74 kB
dist/client/assets/hooks-DGUKDrkD.js 1.76 kB │ gzip: 0.81 kB
dist/client/assets/pretty-bytes-DlqFe0lJ.js 1.80 kB │ gzip: 0.90 kB
dist/client/assets/image-tools-CC-uO7rE.js 2.36 kB │ gzip: 0.92 kB
dist/client/assets/pdf-tools-BfA6X6cX.js 2.38 kB │ gzip: 0.93 kB
dist/client/assets/input-DJT1K7K8.js 2.44 kB │ gzip: 1.25 kB
dist/client/assets/drop-zone-tvplLLJu.js 2.59 kB │ gzip: 1.23 kB
dist/client/assets/useValueChanged-CUvb65Zg.js 3.49 kB │ gzip: 1.42 kB
dist/client/assets/useCompositeItem-NsoGINfq.js 4.11 kB │ gzip: 1.85 kB
dist/client/assets/switch-DXmUCMuj.js 4.42 kB │ gzip: 2.00 kB
dist/client/assets/image.client-CjgJwQ5n.js 4.73 kB │ gzip: 1.98 kB
dist/client/assets/useLabelableId-o6kz9kuv.js 4.80 kB │ gzip: 1.97 kB
dist/client/assets/use-immer.module-D3wpjD-7.js 9.28 kB │ gzip: 3.80 kB
dist/client/assets/image-converter-DgcKrvYR.js 9.50 kB │ gzip: 3.64 kB
dist/client/assets/image-compressor-0J3I7a4a.js 10.07 kB │ gzip: 3.69 kB
dist/client/assets/merge-pdf-CdXkMyOY.js 10.63 kB │ gzip: 3.99 kB
dist/client/assets/routes-G1FJZqrG.js 10.76 kB │ gzip: 3.49 kB
dist/client/assets/image-resize-BGzL7FYs.js 11.00 kB │ gzip: 4.11 kB
dist/client/assets/pdf-to-image-HZm0DqGE.js 11.17 kB │ gzip: 4.31 kB
dist/client/assets/browser-D-PHLAgM.js 11.48 kB │ gzip: 5.64 kB
dist/client/assets/common-Dj_k2Bz4.js 18.36 kB │ gzip: 7.13 kB
dist/client/assets/slider-CMNtKBvW.js 19.54 kB │ gzip: 7.71 kB
dist/client/assets/browser-Bg25_sDh.js 23.47 kB │ gzip: 8.86 kB
dist/client/assets/purify.es-1EvBSpuh.js 24.49 kB │ gzip: 9.56 kB
dist/client/assets/password-generator-C9zLPM3-.js 24.81 kB │ gzip: 9.29 kB
dist/client/assets/qr-generator-DY7Z1c3F.js 26.57 kB │ gzip: 8.59 kB
dist/client/assets/select-D2uC7ypr.js 30.15 kB │ gzip: 10.93 kB
dist/client/assets/usePositioner-B80JBSqh.js 54.16 kB │ gzip: 19.60 kB
dist/client/assets/card-DkRrRv4M.js 54.34 kB │ gzip: 18.34 kB
dist/client/assets/sortable-DMElmqOm.js 110.34 kB │ gzip: 35.84 kB
dist/client/assets/pdf-DfZEJyoA.js 137.66 kB │ gzip: 39.36 kB
dist/client/assets/index.es-DH1ipSb3.js 151.31 kB │ gzip: 48.88 kB
dist/client/assets/html2canvas-CA7kyov8.js 199.49 kB │ gzip: 46.77 kB
dist/client/assets/image-to-pdf-CCeZ2XII.js 403.57 kB │ gzip: 130.80 kB
dist/client/assets/es-C8kTfHMH.js 424.89 kB │ gzip: 177.41 kB
dist/client/assets/index-DMeWptg0.js 425.55 kB │ gzip: 133.71 kB
dist/client/assets/split-pdf-C_0EK33s.js 436.73 kB │ gzip: 130.01 kB

✓ built in 1.78s
vite v8.2.0 building ssr environment for production...
✓ 2300 modules transformed.
computing gzip size...
dist/server/wrangler.json 1.29 kB │ gzip: 0.66 kB
dist/server/.vite/manifest.json 9.03 kB │ gzip: 1.28 kB
dist/server/assets/avif_enc_mt.worker-BSwsqSX3.js 28.17 kB
dist/server/assets/webp_dec-C990n7mh.wasm 137.96 kB │ gzip: 50.00 kB
dist/server/assets/mozjpeg_dec-muSO2n8T.wasm 166.47 kB │ gzip: 64.57 kB
dist/server/assets/image.worker-DDVYh5u9.js 174.50 kB
dist/server/assets/squoosh_png_bg-DAY7U9NW.wasm 181.08 kB │ gzip: 85.73 kB
dist/server/assets/mozjpeg_enc-DO-zoExo.wasm 251.52 kB │ gzip: 60.44 kB
dist/server/assets/webp_enc-BpZvKflB.wasm 281.26 kB │ gzip: 115.98 kB
dist/server/assets/webp_enc_simd-CFvKQ_80.wasm 345.58 kB │ gzip: 128.61 kB
dist/server/assets/avif_dec-B7YOdlSS.wasm 1,170.93 kB │ gzip: 344.65 kB
dist/server/assets/avif_enc-Co4TcJko.wasm 3,485.87 kB │ gzip: 1,136.17 kB
dist/server/assets/avif_enc_mt-DFoVXd45.wasm 3,534.66 kB │ gzip: 1,150.16 kB
dist/server/assets/globals-DD8m-uJz.css 133.07 kB │ gzip: 19.66 kB
dist/server/assets/start-5Z2QO8AU.js 0.14 kB │ gzip: 0.13 kB
dist/server/assets/empty-plugin-adapters-D9UWiqvJ.js 0.22 kB │ gzip: 0.16 kB
dist/server/assets/hammer-foCtYLGa.js 0.66 kB │ gzip: 0.42 kB
dist/server/assets/mail-CbzGYPLj.js 0.79 kB │ gzip: 0.39 kB
dist/server/assets/palette-Dphdfq4p.js 0.85 kB │ gzip: 0.42 kB
dist/server/assets/badge-CZCRVk3x.js 1.82 kB │ gzip: 0.83 kB
dist/server/assets/trust-bar-XEwBN1do.js 2.75 kB │ gzip: 1.12 kB
dist/server/assets/image-to-pdf-0BmyndT3.js 2.84 kB │ gzip: 1.13 kB
dist/server/assets/image-resize-Cz1kUD1r.js 3.17 kB │ gzip: 1.32 kB
dist/server/assets/hooks-RLPIEwXK.js 3.20 kB │ gzip: 0.98 kB
dist/server/assets/image-compressor-BKIaMalc.js 3.21 kB │ gzip: 1.32 kB
dist/server/assets/password-generator-BPUvH90H.js 3.25 kB │ gzip: 1.23 kB
dist/server/assets/image-converter-Du9lcFwH.js 3.26 kB │ gzip: 1.27 kB
dist/server/assets/qr-generator-CcWpMpz_.js 3.43 kB │ gzip: 1.39 kB
dist/server/assets/faq-section-Zx_pYCwt.js 3.81 kB │ gzip: 1.11 kB
dist/server/assets/pdf-tools-DWsR9HnR.js 4.03 kB │ gzip: 1.22 kB
dist/server/assets/image-tools-B_g3lSYg.js 4.05 kB │ gzip: 1.22 kB
dist/server/assets/split-pdf-0dH2r3g1.js 6.10 kB │ gzip: 1.95 kB
dist/server/assets/_tanstack-start-manifest_v-BqH9Yi0T.js 6.22 kB │ gzip: 1.27 kB
dist/server/assets/site-BfTsAHjR.js 6.79 kB │ gzip: 1.95 kB
dist/server/assets/merge-pdf-DqSYJ68A.js 6.80 kB │ gzip: 2.29 kB
dist/server/assets/link-DBMHWm_O.js 8.27 kB │ gzip: 2.69 kB
dist/server/assets/routes-D6ZsoboU.js 17.14 kB │ gzip: 4.33 kB
dist/server/assets/react-dom-BwOCpxiD.js 26.26 kB │ gzip: 6.80 kB
dist/server/assets/pdf-to-image-DJEyb8xD.js 26.65 kB │ gzip: 7.90 kB
dist/server/assets/common-DyBxDLsH.js 50.31 kB │ gzip: 12.21 kB
dist/server/assets/useStore-bEagTgYF.js 50.34 kB │ gzip: 13.51 kB
dist/server/assets/Match-D2Fo24Tl.js 109.54 kB │ gzip: 26.33 kB
dist/server/assets/card-Gqaf4sce.js 129.73 kB │ gzip: 27.26 kB
dist/server/assets/router-Ddc-7bjg.js 456.90 kB │ gzip: 97.93 kB
dist/server/index.js 619.24 kB │ gzip: 128.85 kB

✓ built in 1.00s
[prerender] Prerendering pages...
[prerender] Concurrency: 14
[prerender] Crawling: /
[prerender] Crawling: /image-compressor
[prerender] Crawling: /image-converter
[prerender] Crawling: /image-resize
[prerender] Crawling: /image-to-pdf
[prerender] Crawling: /image-tools
[prerender] Crawling: /merge-pdf
[prerender] Crawling: /password-generator
[prerender] Crawling: /pdf-to-image
[prerender] Crawling: /pdf-tools
[prerender] Crawling: /qr-generator
[prerender] Crawling: /split-pdf
GET /image-compressor/ 307 Temporary Redirect (7ms)
GET /image-converter/ 307 Temporary Redirect (6ms)
GET / 200 OK (119ms)
GET /image-resize/ 307 Temporary Redirect (6ms)
GET /image-to-pdf/ 307 Temporary Redirect (5ms)
GET /image-tools/ 307 Temporary Redirect (6ms)
GET /merge-pdf/ 307 Temporary Redirect (6ms)
GET /password-generator/ 307 Temporary Redirect (5ms)
GET /pdf-to-image/ 307 Temporary Redirect (5ms)
GET /pdf-tools/ 307 Temporary Redirect (6ms)
GET /qr-generator/ 307 Temporary Redirect (5ms)
GET /split-pdf/ 307 Temporary Redirect (5ms)
GET /image-converter 200 OK (17ms)
GET /image-compressor 200 OK (13ms)
GET /image-resize 200 OK (11ms)
GET /image-to-pdf 200 OK (10ms)
GET /image-tools 200 OK (10ms)
GET /merge-pdf 200 OK (13ms)
GET /password-generator 200 OK (10ms)
GET /pdf-to-image 200 OK (12ms)
GET /pdf-tools 200 OK (9ms)
GET /qr-generator 200 OK (10ms)
GET /split-pdf 200 OK (10ms)
[prerender] Prerendered 12 pages:
[prerender] - /image-converter
[prerender] - /image-compressor
[prerender] - /image-resize
[prerender] - /image-tools
[prerender] - /image-to-pdf
[prerender] - /merge-pdf
[prerender] - /pdf-tools
[prerender] - /password-generator
[prerender] - /
[prerender] - /pdf-to-image
[prerender] - /qr-generator
[prerender] - /split-pdf
[sitemap] Building Sitemap...
[sitemap] Writing sitemap XML at dist\client\sitemap.xml
[sitemap] Writing pages data at dist\client\pages.json

Contributor guide

Open the contributing guide

Research direction

Start with the linked browserstay reproduction and run `bun run build`; compare the `dist/client/assets` and `dist/server/assets` outputs. Trace how `image.worker.ts` and its `@jsquash/*` imports enter the TanStack Start SSR graph through `@cloudflare/vite-plugin`, using the Nitro build as a control. Done means the worker and WASM assets remain in the client output without being emitted into server assets.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript, vite, wasm
Domain
build-system
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.