JORVEL

Production checklist

Before flipping the DNS, confirm every item below. Items link to the feature that implements them. Copy this list into your release-readiness doc and sign off item by item.

Anything unchecked is a launch blocker

Don't treat the checklist as aspirational. Each item exists because skipping it has cost a production incident somewhere. If a check doesn't apply to your shape, write down why and move on; don't silently skip.

Security

Federation increases the trust surface — untrusted remotes, hydration payloads, and CDN tampering are all in play. Lock each one down before going live.

  • Content-Security-Policy header set on every HTML response (buildCsp)Use strict-dynamic + a base64url nonce per response. Loose CSPs are worse than none.
  • SRI integrity attribute on every remoteEntry.js script tagGenerated by federation.sri.algo = "sha384". Block-on-mismatch in production.
  • RemoteAllowlist wired to getRemoteRegistryReject URLs outside the configured origins — defense in depth even with SRI.
  • All inline state serialized via safeJsonForScript or serializeStateBoth escape </script>, line-separator (U+2028) and paragraph-separator (U+2029).
  • HTTPS only — HSTS header emitted with includeSubDomains + preload
  • CORS restricted to known origins (no wildcard in prod)
  • Secrets stored in the platform secret manager — never in .env checked in
  • Rate limiting on auth endpoints (@jorvel/security rate-limit)

Observability

When a remote fails, the host blinks but the failure must be obvious to oncall. Wire metrics + errors before launch, not after the first incident.

  • Error reporting adapter installed (Sentry / Rollbar / OTel)
  • collectWebVitals() called in the shell bootstrap
  • Structured logger writing JSON to a collector
  • Alerts configured for error rate, p95 LCP, remote-load error rateSet the threshold above noise but below user-visible degradation.
  • onRemoteLoad telemetry feeds the same RUM pipeline as page metrics
  • Source maps uploaded to the error tracker (gated behind the build hash)
  • jorvel version printed in every error report (audit trail)

Performance

Each remote pays a network round-trip on first load. Budget it, monitor it, and reject regressions in CI.

  • jorvel perf budgets green in CI
  • Bundle analyzer (jorvel analyze) reviewed before each release
  • Remote preload tags in SSR head (remoteEntryPreloads)
  • Cache-Control tuned per route (cacheControl helper)Immutable for hashed assets; short max-age for HTML; SWR for remote manifests.
  • Assets hashed and served with immutable cache-control
  • Compression (gzip + brotli) enabled at the edge
  • Image derivatives generated for every breakpoint (jorvel image)
  • Fonts preloaded with crossorigin=anonymous

Reliability

A remote crash should be a tile-level failure, not a page-level failure. Boundaries, health checks, fallbacks.

  • Health check endpoint per remotefetchHealth() can gate a load — fast-fail beats a 30s timeout.
  • RemoteRegistry fetches manifest with retry + exponential backoff
  • Error boundary around every RemoteOutlet
  • Version mismatch warnings surfaced in logs (checkRuntimeVersions)
  • Graceful fallback UI when a remote fails to load
  • Blue/green or weighted-remote rollout for risky changes
  • Service Worker offline fallback page tested end-to-end

Deploy

Production parity matters — the staging environment should diverge in data, not in topology.

  • Adapter scaffolded (Vercel / Cloudflare / Node / Docker)
  • CDN publicPath set in jorvel.config.json
  • Preview deploy per PR (jorvel ci affected)
  • Rollback plan documented and rehearsed
  • Smoke tests run against the deploy URL before flipping DNS
  • CDN cache purged on release (or version-namespaced URLs)

Release process

Predictable releases need predictable artifacts. Changesets + SemVer + tags carry the audit trail.

  • Changesets workflow on main
  • SemVer for every published package
  • CHANGELOG.md per package up to date
  • Git tags for each release
  • Linked packages bump together: [runtime, ssr, security] etc.
  • Release notes posted to the team channel before flipping flags

Release-day runbook

  1. T-24h: changeset PR merged. CI green. Preview deploy hit by team for smoke checks.
  2. T-1h: announce in the team channel. Page the on-call to standby. Roll forward the feature flag to off-for-everyone.
  3. T-0: tag the release. CI publishes packages + deploys the host + each remote. Wait for the deploy job to complete.
  4. T+5m:run smoke tests against production URLs. Confirm error rate flat, LCP flat, remote-load error rate < baseline.
  5. T+10m: flip the feature flag to 10%. Watch the dashboards.
  6. T+30m: if metrics are clean, ramp to 50%. Otherwise revert.
  7. T+60m: ramp to 100%. Close the release ticket. Post a summary with deltas in error rate, LCP, and bundle size.

Rollback plan

  1. Feature-flag revert first if the issue is gated. Sub-minute mitigation.
  2. Deploy revert — re-deploy the previous tag via the platform UI. ~3 min.
  3. CDN cache purge if the issue is a stale chunk. The SW will pick up the new bytes on next visit; for in-session users, broadcast a refresh prompt.
  4. Hotfixonly if revert isn't an option. Branch from the released tag, cherry-pick the fix, ship through the same pipeline.