Skip to content

fix(build): copy schema.json to dist and externalize zod#534

Merged
ochafik merged 1 commit intomainfrom
fix/build-schema-json-and-zod-external
Mar 6, 2026
Merged

fix(build): copy schema.json to dist and externalize zod#534
ochafik merged 1 commit intomainfrom
fix/build-schema-json-and-zod-external

Conversation

@ochafik
Copy link
Contributor

@ochafik ochafik commented Mar 6, 2026

Summary

Two focused packaging fixes in build.bun.ts.

Bug 1: ./schema.json export was broken

package.json exports "./schema.json": "./dist/src/generated/schema.json" but nothing copied the file there — tsc is emitDeclarationOnly and Bun.build doesn't emit JSON assets. Consumers importing @modelcontextprotocol/ext-apps/schema.json got ERR_MODULE_NOT_FOUND.

Fix: cpSync the file after tsc runs.

Bug 2: zod bundled despite being a peerDependency

zod is declared as a peer in package.json but was absent from every external list in build.bun.ts, so it was bundled into every entry point. This causes dual-instance bugs: consumer-side instanceof ZodError checks and schema.extend() calls break when operating across two separate zod runtimes.

Fix: Add zod to the external list for all non-*-with-deps entries. app-with-deps intentionally bundles everything and is left unchanged.

Bundle size impact

Entry Before After Δ
app.js 293,952 24,561 −91.6%
app-bridge.js 299,517 30,112 −89.9%
react/index.js 295,558 26,153 −91.2%
server/index.js 291,500 22,135 −92.4%
app-with-deps.js 321,814 321,814 unchanged

Total shipped JS: ~1.50 MB → ~0.42 MB

Verification

# schema.json now present
$ ls dist/src/generated/schema.json
-rw-r--r--  216501  dist/src/generated/schema.json

# zod now external (import, not bundled)
$ rg -o 'ZodError|ZodType' dist/src/app.js | wc -l
0
$ rg -o 'from"zod"' dist/src/app.js | wc -l
1

# bundles load
$ node -e 'import("./dist/src/app.js").then(m => console.log(Object.keys(m).length))'
# → 38 exports

# unit tests pass
$ npm test
# → 87 pass, 0 fail

Two packaging bugs:

1. The './schema.json' export pointed to dist/src/generated/schema.json
   but nothing copied it there (tsc is emitDeclarationOnly, Bun.build
   doesn't emit JSON). Consumers got ERR_MODULE_NOT_FOUND.
   Fix: cpSync after tsc runs.

2. zod is a peerDependency but was bundled into every entry point
   (~270KB each). This causes dual-instance bugs where consumer-side
   'instanceof ZodError' and schema.extend() break across boundaries.
   Fix: add zod to external list for all non-with-deps entries.

Bundle size impact:
  app.js          293952 -> 24561  (-91.6%)
  app-bridge.js   299517 -> 30112  (-89.9%)
  react/index.js  295558 -> 26153  (-91.2%)
  server/index.js 291500 -> 22135  (-92.4%)
  app-with-deps   321814 -> 321814 (unchanged, intentional)
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 6, 2026

Open in StackBlitz

@modelcontextprotocol/ext-apps

npm i https://pkg.pr.new/@modelcontextprotocol/ext-apps@534

@modelcontextprotocol/server-basic-preact

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-preact@534

@modelcontextprotocol/server-basic-react

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-react@534

@modelcontextprotocol/server-basic-solid

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-solid@534

@modelcontextprotocol/server-basic-svelte

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-svelte@534

@modelcontextprotocol/server-basic-vanillajs

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-vanillajs@534

@modelcontextprotocol/server-basic-vue

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-vue@534

@modelcontextprotocol/server-budget-allocator

npm i https://pkg.pr.new/@modelcontextprotocol/server-budget-allocator@534

@modelcontextprotocol/server-cohort-heatmap

npm i https://pkg.pr.new/@modelcontextprotocol/server-cohort-heatmap@534

@modelcontextprotocol/server-customer-segmentation

npm i https://pkg.pr.new/@modelcontextprotocol/server-customer-segmentation@534

@modelcontextprotocol/server-debug

npm i https://pkg.pr.new/@modelcontextprotocol/server-debug@534

@modelcontextprotocol/server-map

npm i https://pkg.pr.new/@modelcontextprotocol/server-map@534

@modelcontextprotocol/server-pdf

npm i https://pkg.pr.new/@modelcontextprotocol/server-pdf@534

@modelcontextprotocol/server-scenario-modeler

npm i https://pkg.pr.new/@modelcontextprotocol/server-scenario-modeler@534

@modelcontextprotocol/server-shadertoy

npm i https://pkg.pr.new/@modelcontextprotocol/server-shadertoy@534

@modelcontextprotocol/server-sheet-music

npm i https://pkg.pr.new/@modelcontextprotocol/server-sheet-music@534

@modelcontextprotocol/server-system-monitor

npm i https://pkg.pr.new/@modelcontextprotocol/server-system-monitor@534

@modelcontextprotocol/server-threejs

npm i https://pkg.pr.new/@modelcontextprotocol/server-threejs@534

@modelcontextprotocol/server-transcript

npm i https://pkg.pr.new/@modelcontextprotocol/server-transcript@534

@modelcontextprotocol/server-video-resource

npm i https://pkg.pr.new/@modelcontextprotocol/server-video-resource@534

@modelcontextprotocol/server-wiki-explorer

npm i https://pkg.pr.new/@modelcontextprotocol/server-wiki-explorer@534

commit: e9aaf1e

@ochafik ochafik marked this pull request as ready for review March 6, 2026 16:29
@ochafik ochafik requested a review from jonathanhefner March 6, 2026 16:29
@ochafik ochafik merged commit 79744af into main Mar 6, 2026
20 checks passed
ochafik added a commit that referenced this pull request Mar 6, 2026
The react-with-deps build entry was introduced in PR #221 (e078250) as a
sibling to app-with-deps for CDN/unpkg no-bundler use. But its external
array was duplicated without editing — it never dropped @modelcontextprotocol/sdk
from externals, so it has shipped byte-identical to ./react for 10 releases
(v0.3.1 → v1.2.0).

After #534 merged, both entries use ['react', 'react-dom', ...PEER_EXTERNALS]
— still identical, just smaller.

Delete rather than fix: React apps always use a bundler; the CDN/unpkg
use case (HTML-string apps like qr-server) doesn't apply to React hooks.
Zero consumers verified (examples/docs/tests/plugins).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants