Bundle bloat: importing from @finos/fdc3 pulls the entire @finos/fdc3-schema runtime (~240 KB)
- Dominant language
- TypeScript
- Stars
- 270
- Forks
- 193
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 36
Description
## Minor Issue
Upgrading `@finos/fdc3` from 2.1.x to 2.2.3 grew our minified ESM bundle by **181 KB**.
Marking `@finos/*` as `sideEffects: false` at resolve time in our bundler narrowed the
regression to **158 KB** but didn't fix it — the remainder is structural (see details below).
### Area of Issue
- [ ] App Directory
- [ ] API
- [ ] Context Data
- [ ] Intents
- [ ] Desktop Agent Bridging
- [ ] Use Cases
- [x] Other
### Issue Description
Importing only `getAgent` / `fdc3Ready` from `@finos/fdc3` pulls in the entire
`@finos/fdc3-schema` runtime (~240 KB), even when the consumer never references
`BrowserTypes` or `BridgingTypes`.
#### Root cause
`@finos/fdc3-schema/dist/src/index.js`:
```js
import * as BrowserTypes from '../generated/api/BrowserTypes.js';
import * as BridgingTypes from '../generated/bridging/BridgingTypes.js';
export { BrowserTypes, BridgingTypes };
```
The `import * as` namespace binding is opaque to bundlers — any reachability of
`BrowserTypes` retains the whole module. The two generated modules are ~146 KB and
~94 KB of quicktype output (`Convert` classes plus type-guard helpers).
The umbrella `@finos/fdc3` then re-exports both namespaces, so any consumer that imports
from it makes the schema reachable:
```js
// @finos/fdc3/dist/src/index.js
import { BrowserTypes, BridgingTypes } from '@finos/fdc3-schema';
export { BridgingTypes, BrowserTypes };
```
Within `@finos/fdc3-get-agent`, the modules that introduce a runtime import of
fdc3-schema (and therefore force it into any reachable graph) are:
- `strategies/HelloHandler`
- `strategies/IdentityValidationHandler`
- `ui/AbstractUIComponent`
- `ui/DefaultDesktopAgentChannelSelector`
- `ui/DefaultDesktopAgentIntentResolver`
(`@finos/fdc3-agent-proxy/listeners/PrivateChannelEventListener` is in the same
position.)
#### Options for cutting it down
1. **Add `"sideEffects": false`** to every `@finos/*` package. None of the six 2.2.3
packages declare it today.
2. **Replace `import * as` with named re-exports** in
`@finos/fdc3-schema/dist/src/index.js` so bundlers can drop symbols at export-name
granularity instead of keeping the entire 146 KB / 94 KB namespaces because
anything in them was reached.
3. **Add an `exports` map with sub-paths** to `@finos/fdc3-schema` so consumers can
opt in to the narrowest slice (e.g. types vs. validators) without bundlers having
to prove the rest is unused.
4. **Split the generated `Convert` class out of the type-only exports.** Most of the
240 KB is the `Convert` runtime (162 static methods on `BrowserTypes` alone) plus
its type-guard helpers. Consumers wanting only TypeScript types pay the full
runtime cost. A separate entry point for validators would let consumers that don't
need runtime schema validation skip it entirely.
### Additional Context
Contributor guide
Assessment
This issue has not been assessed yet.