Skip to content

Consider bundling React same-origin instead of externalizing to esm.sh #313

Description

@Stvad

Context

Follow-up from PR #309. React (+ react-dom, scheduler) is currently externalized to esm.sh in production via an import map (vite-plugins/reactImportMapMode.ts), with SRI integrity. Because those URLs are absolute + cross-origin, they're excluded from the service worker's dist/-walking same-origin precache.

In #309 we closed the resulting offline gap with option A: the SW now precaches the exact import-map integrity set (the esm.sh React URLs) into its shared vendor cache at install, so a controlled offline load can resolve React. That makes offline work, but keeps the cross-origin dependency and a bespoke vendor-precache path.

This issue tracks option C: stop externalizing React and bundle it same-origin instead.

Why it might be worth doing

  • Simpler offline story. Same-origin React would be emitted under dist/ and covered automatically by the existing full-graph precache — no separate precacheVendor list, no import-map integrity plumbing, no cross-origin km-vendor cache.
  • One fewer external dependency at boot. Today a cold first load reaches esm.sh for React; a same-origin bundle removes that third-party runtime dependency (availability, SRI-pinning, CDN policy).
  • Generation consistency for React too. Same-origin React would live in each generation's namespaced asset cache like everything else, rather than a shared un-namespaced vendor cache.

Why we externalized in the first place (trade-offs to weigh)

  • esm.sh gives a shared, immutable, cross-origin-cached React that multiple deploys/previews reuse without re-downloading.
  • Externalizing keeps React out of the same-origin bundle, shrinking first-party JS.
  • The import map lets user extensions import react/react-dom by bare specifier at runtime and resolve to the same singleton React the app uses. Bundling must preserve this — extensions still need a single shared React instance (e.g. expose it on a same-origin module the import map points at, rather than an esm.sh URL). This is the load-bearing constraint and the main reason to think carefully before switching.

Scope

  • Evaluate whether bundling React same-origin (while preserving the single-shared-instance guarantee for user extensions) is worth the bundle-size / CDN-cache trade.
  • If yes: point the production import map at a same-origin React module, drop productionReactIntegrity + the SW precacheVendor path (option A becomes unnecessary), and confirm extensions still resolve one shared React.

Not urgent — offline works today via option A. This is a simplification/robustness question, not a bug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions