finos / finos/FDC3

Bundle bloat: importing from @finos/fdc3 pulls the entire @finos/fdc3-schema runtime (~240 KB)

Open
#1,901 2 comments 0 reactions 2 assignees Claimed by @hughtroeger View on GitHub
enhancement FDC3 for Web Browsers javascript needs backport
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.