Bundle size
What each piece of Comvi i18n weighs, and which import adds it.
Figures are min+gz, produced by pnpm size and measured through each package’s published exports map rather than a dist/ path, so what is measured is what an installed app resolves. A framework’s own runtime is left out, so a framework row is the Comvi code only.
CI re-measures every row against its recorded baseline with 5% of headroom and fails when a row exceeds that budget, so a regression inside the margin passes.
What it weighs
Section titled “What it weighs”| app shape | measured as | min+gz |
|---|---|---|
@comvi/core alone, nothing composed |
core-base |
5270 B |
@comvi/core + ICU |
core-base-icu |
6502 B |
| every core capability composed | core-full-composite |
9389 B |
@comvi/react, bare instance + bindings |
fw-react-default |
7369 B |
@comvi/react, every capability composed |
fw-react-full-composite |
12262 B |
@comvi/react + ICU + the CDN loader |
platform-path-react |
11353 B |
| core + ICU + the CDN loader | plugin-fetch-loader |
9692 B |
Every figure names its fixture, and each fixture is a gated row in scripts/size-budgets.json in the comvi-js repository. Rows one and two give the price of ICU, 1232 B, which is why it is the compiler constructor option rather than a default. Rows one and four give the price of the React bindings over the core floor, 2099 B. Rows four and five bracket a React app: the bindings alone against everything composed.
core-full-composite recomposes /tags, /icu, /loader, /plugins and /devtools.
The two loader entries
Section titled “The two loader entries”The root entry of @comvi/plugin-fetch-loader is the CDN request path on its own. fetchLoader from @comvi/plugin-fetch-loader/api chooses between the CDN and the API at runtime, so it carries both request paths whether or not you reach them.
| graph | measured as | min+gz |
|---|---|---|
bare instance, ICU, and the /api entry |
plugin-fetch-loader-api |
11711 B |
| bare instance, ICU, and the root entry | plugin-fetch-loader |
9692 B |
An app that only reads a public bundle swaps fetchLoader for cdnLoader and drops 2019 B with the API path. Keep fetchLoader wherever the i18n instance has an apiKey. See CDN mode vs API mode.
The import-map adapter behind .use(loader(map)) is in your graph only when you hand over a map: attachLoader does not name it, so an instance that registers a plain loader function never carries it.
Where the weight comes from
Section titled “Where the weight comes from”Every capability is an import you add, so the floor is the bare instance and each capability is a line in your own composition.
- Nothing arrives switched off. An absent capability’s module never entered the bundle, which is why a missing one is a TypeScript error rather than a runtime no-op.
- No
evaland nonew Functionin any runtime package, so everything runs under a strict CSP withoutunsafe-eval. @comvi/corehas zero runtime dependencies.- The
unpkg/jsdelivrglobal build is the one exception and still carries everything: a<script src>consumer has no import graph to extend.
Read next
Section titled “Read next”.use(installer): the i18n instance, and what each installer adds to it.- Fetch loader: why the root entry carries two request paths, and when to use which.
- Pluralize with ICU: what the 1232 B buys: plural, select and selectordinal per framework.