modelcontextprotocol / modelcontextprotocol/ext-apps
app-bridge pulls in entire Zod library (~1.4MB pre-minified) - most of it unused
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2.9k
- Forks
- 387
- Avg merge
- 3h 21m
- Merged PRs (30d)
- 6
Description
Summary
When importing AppBridge and PostMessageTransport from @modelcontextprotocol/ext-apps/app-bridge, the bundle includes ~1.65MB of dependencies (pre-minified), resulting in a 377KB minified bundle for a minimal host app. The vast majority is Zod code that cannot be tree-shaken.
Reproduction
// Minimal import - just AppBridge for host-side integration
import { AppBridge, PostMessageTransport } from '@modelcontextprotocol/ext-apps/app-bridge';
Expected bundle impact: ~50KB (bridge + protocol logic)
Actual bundle impact: ~377KB minified (1.65MB pre-minified)
Bundle Analysis (ext-apps@1.7.1)
| Package | Pre-minified Size | Modules |
|---|---|---|
| zod@4.3.6 | 1,386 KB | 139 |
| @modelcontextprotocol/sdk@1.27.1 | 172 KB | 6 |
| zod-to-json-schema | 53 KB | 39 |
| @modelcontextprotocol/ext-apps@1.7.1 | 42 KB | 1 |
| Total | 1,653 KB | 185 |
Zod Breakdown
The Zod library is the primary culprit at 1,386KB (84% of total):
| Zod Component | Size | Notes |
|---|---|---|
| Locales (48 languages) | 485 KB | ar, bg, cs, da, de, en, es, fa, fi, fr, he, hu, id, it, ja, ko, nl, no, pl, pt, ru, sv, th, tr, uk, vi, zh-CN, zh-TW, etc. |
| v4 core + classic | 982 KB | Full v4 API |
| v3 compatibility | 146 KB | Legacy v3 API |
| v4-mini | 33 KB | Minimal v4 |
Why This Happens
- Zod v4 bundles all locales by default - 48 locale files are included even though most apps only need 1-2
- Multiple Zod versions included - v3, v4, v4-classic, v4-mini are all bundled
- Cannot be tree-shaken - The MCP SDK imports from zod which pulls in the full package
Suggested Solutions
- Use Zod v4-mini - If only runtime validation is needed (not JSON schema generation), v4-mini is ~33KB vs ~1MB
- Externalize Zod as peer dependency - Let consumers provide Zod, enabling deduplication and locale subsetting:
"peerDependencies": {
"zod": "^4.0.0"
}
- Subset locales - Only bundle en locale by default, let consumers add others:
import { z } from 'zod/v4-mini'; // or zod/v4/core with manual locale
-
Lazy-load schema validation - If Zod is only needed for certain operations, dynamically import it
Environment
-
@modelcontextprotocol/ext-apps: 1.7.1
-
@modelcontextprotocol/sdk: 1.27.1
-
zod: 4.3.6
-
Bundler: Webpack 5.x (production mode)
Workaround
-
We implemented dynamic import() to lazy-load the app-bridge chunk only when MCP protocol is used, reducing our main bundle from 812KB to 358KB. The MCP chunk (377KB) loads on-demand.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the AppBridge and PostMessageTransport entry points and inspect their dependency graph, focusing on how the MCP SDK imports Zod. Reproduce the Webpack bundle analysis with the minimal import, then verify that the unused Zod versions and locales are no longer included and that the bundle approaches the reported expected size.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100