feat(react): harden bundle boundaries and modernize Inter delivery - #5312
feat(react): harden bundle boundaries and modernize Inter delivery#5312somebody32 wants to merge 15 commits into
Conversation
🔍 Review policy: FeatureThe PR title starts with Module ownership (via CODEOWNERS)
Declared in each module's Required approvals
How this was decided
Policy source: |
✅ No untranslated copy addedEvery user-visible string in this PR comes from the i18n layer. Codebase total unchanged at 133. |
✅ Storybook docs — no pages lostEvery page reachable on Links point at this PR's Storybook build — browse the full Storybook. Snapshot of the Storybook index (docs pages + stories) compared against |
📦 Alpha Package Version PublishedUse Use |
♿ Accessibility (axe) — components changed in this PR18 issues across 18 stories — all non-blocking (
Scope: only stories in the files/component folders this PR changed. It can't yet flag downstream ripple from shared-code/token changes, or diff against |
🔍 Visual review for your branch is published 🔍Here are the links to: |
|
📱 Expo Go Preview Published
LinksQR Code |
…time-boundaries # Conflicts: # packages/react/package.json
What
dist/*artifacts and deep-path contract for compatibility?urlassets in pack-safe internal modulesWhy
The bundled root was the production problem. A consumer asking for one component received a pre-bundled
f0.js, so its bundler could not recover the original module boundaries. The live Factorial-agent Cloudflare branch also reproduced browser-unsafe CommonJS React loading and missing font assets.The CSS had the same boundary failure in a different form. Three broad safelist expressions generated every background, text, and border semantic token with hover, focus, and active variants. The font publisher then embedded six WOFF binaries as base64. The result was a 3.0 MB stylesheet even when a consumer only requested one component.
This PR publishes the original ESM module graph as the modern JavaScript contract and a closed CSS plus asset graph as the style contract. The legacy bundled distribution remains available so existing deep imports are not broken.
Current-head production evidence
All measurements below use the packed npm artifact, not source aliases.
F0Buttoncomponent subpathF0Buttonpackage rootF0Dialog+F0ButtonsubpathsThe package-root Button probe was 9,057,121 bytes before the preserved ESM change. It is now approximately 611 KiB: a 93% raw reduction, and remains within 5% of the explicit Button subpath.
Global-style consumer CSS changed as follows:
The standalone published
dist/styles.cssis 330,862 B raw, 49,108 B gzip, and 32,710 B Brotli. It contains relativefonts/*.woff2references and no embedded data URLs. The packed-consumer gate confirms all 16 variable subsets are present underdist/fonts, and rejects missing, escaping, or non-file relative references. Compared with the previous static-face CSS, the complete stylesheet adds 3,558 B raw, 630 B gzip, and 396 B Brotli.The retained-module baseline remains a ratchet: new retained features or byte growth fail CI.
Font scope
F0 is now the single owner of browser Inter delivery. Product consumers should load the F0 stylesheet and must not maintain a second Factorial-side Inter source. The package upgrades from Inter 3.3 static WOFF faces to the official Inter 4.1 release: normal and italic variable WOFF2, optical sizing from 14 to 32, and the supported product weight range from 400 to 700.
Each style is split into Cyrillic Extended, Cyrillic, Greek Extended, Greek, symbols, Vietnamese, Latin Extended, and Latin unicode ranges. Browsers therefore fetch only the script/style subsets used by a page, while one variable file covers every requested weight. The Latin upright subset is 75,592 B for all 400-700 weights; Latin upright plus italic is 157,440 B. The complete 16-file set is 796,296 B, slightly below the previous six static faces at 799,640 B.
The CSS uses CSS Fonts Level 4
format("woff2") tech(variations),font-display: swap, and fallback metrics generated from Inter 4.1. We intentionally do not use experimental incremental font transfer: it is not an evergreen browser baseline.The historical static WOFF files are removed from the package. Their paths were never the stylesheet contract; consumers should use
@factorialco/f0-react/styles.cssrather than importing font binaries directly.Package integrity gates
The build now fails if:
node_modulesdirectoryHonest remaining weight
This fixes publication and tree-shaking; it does not make every component dependency graph lean.
F0Buttonstill retains roughly 581 KiB raw through shared Tooltip, Motion, i18n, emoji, andOneEllipsisboundaries.F0Dialogstill retains the complete avatar and flag capability through its optional resource header and remains roughly 3.9 MiB raw. Those are real source dependency problems for follow-up work, not barrel or build artifacts hidden by this PR.The paired Factorial custom-app host must serve the relative font assets next to the stylesheet. This PR makes that contract generic and testable in the F0 tarball; it does not modify the Factorial-agent repository or duplicate work owned by its live thread.
Compatibility and scope
Validation
No screenshots: there is no intended production visual change.