Skip to content

feat: make TanStack Redact the default React runtime - #264

Merged
BleedingDev merged 13 commits into
main-ultramodernfrom
feat/redact-default-20261028
Oct 29, 2026
Merged

BleedingDev merged 13 commits into
main-ultramodernfrom
feat/redact-default-20261028

Conversation

@BleedingDev

@BleedingDev BleedingDev commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Redact | npm @bleedingdev/tanstack-redact | rsbuild-redact-plugin | Redact fixes #102 #103 #104 #108 #109 #110 #112 | plugin #1

Why the change

Every UltraModern React app, new or upgraded, now renders with TanStack Redact on the server and in the browser with no app edits, so it ships far less React runtime JS while server HTML, useId values and hydration stay consistent.

Special things to note

  • app-tools installs Redact as npm:@bleedingdev/tanstack-redact@0.2.1. That is the signed, provenance-attested publish of the reviewed patch from chore(supply): publish the patched Redact sidecar from main #266. It is our own sidecar, so that exact version is exempt from the 24-hour release-age gate. Any cohort manifest that names upstream @tanstack/redact fails to publish.
  • Redact 0.2.1 had streaming SSR bugs (useId order, duplicate IDs, table/SVG streaming, segment IDs, element-root metadata, error bubbling, pending-range deletion, and boundaries that finish before the first read never being inlined, which breaks no-JS MF pages). The sidecar carries the fixes, and they are sent upstream in the PRs linked above. The framework refuses to build with an unpatched Redact.
  • redact: false keeps real React everywhere. RSC apps stay on real React automatically, because the Flight client needs React internals that Redact does not have.

Change outline

The default comes from the framework, not from templates, so upgrades get it too.

 defineConfig({ renderer: 'react', ... })          // unchanged app config
   composeReactRenderer
+    @modern-js/ultramodern-redact-integration
+      redact === false       -> real React
+      server.rsc             -> real React (logged once)
+      CSR only               -> rsbuild-redact-plugin (pluginRedact)
+      SSR / workerd / MF SSR -> same alias table on web + node + workerSSR
+      assert installed Redact carries the reviewed patch marker
type UltramodernAppUserConfig = {
  // ...
  redact?: boolean | { viewTransitions?: boolean } // default: true
}

Runtime identity follows what is actually aliased, not the package name.

 Module Federation shared react / react-dom / jsx
-  version from the react package
+  effective runtime: redact@0.2.1 or react@19.3.1
+  host and remote on different runtimes -> build error
 persistent cache identity
+  hash of the installed runtime manifest and dist files

Supply chain and release:

 packages/solutions/ultramodern-app-tools/package.json
-  "@tanstack/redact": "0.2.1"
+  "@tanstack/redact": "npm:@bleedingdev/tanstack-redact@0.2.1"
 pnpm-workspace.yaml minimumReleaseAgeExclude
+  '@bleedingdev/tanstack-redact@0.2.1'      owned sidecar, exact version
 scripts/ultramodern-supply
-  unpublishedForkEdges: app-tools @tanstack/redact (CI-only rewrite)
+  upstream @tanstack/redact in any cohort manifest -> declare the alias

One dev-server race fixed along the way. It already failed macOS CI on #263 and #266:

 native development, Module Federation remote
   edit -> compile A finishes, hot update emitted -> edit -> compile B published
-  A skipped as stale, its graph never kept
-  runtime applies A's update -> lazy import from A's graph dir -> 404
+  every compiler records its finished graph in its done hook
+  each publication pass keeps those graphs (same 256 MiB budget)

Small generic runtime hooks in upstream-owned files, recorded in FORK-DIVERGENCE.md:

 StreamSSRExtender
+  processResponseStream(stream)   // runs on the completed document stream
 custom Document child compiler
-  always externalizes react / react-dom
+  skips externals that the parent compiler aliases

Generator and proofs:

 ultramodern-create
+  @tanstack/redact and rsbuild-redact-plugin count as React-owned packages
+  generated apps declare neither package and add no age exemptions
 worker lifecycle proof
+  runs twice: default (Redact compiled, no react-dom) and redact: false
 tests/integration/renderer-react
+  /redact route: streamed useId, table row, SVG, late reveal after hydration
+  Node and workerd: same DOM nodes kept, ids unchanged, clicks work

Validation before the rebase onto main-ultramodern with the signed sidecar:

renderer-react integration   default 24/24, redact:false 24/24, HMR pass
ultramodern-app-tools        focused 176/176; full suite red only on 6
                             pre-existing missing-module fixture files
ultramodern-create           464/464
supply / publication         133/133, 16/16, 44/44
patched Redact               2,088 tests on source and on patched dist
isolated packed consumer     sidecar install, default CSR + SSR build pass
boundary gate                0 forbidden imports, 0 divergence violations

After switching to the published sidecar:

installed sidecar            dist/server/stream.js line 1 = v1 marker
supply / publication         127/127, check-overrides pass
app-tools Redact + MF        72/72
divergence gate              0 violations
native-development           8/8 full-file runs; new superseded-graph test
                             reproduced the CI 404 before the fix
native-composition           1030/1030

🤖 Generated with Claude Code

@github-actions

Copy link
Copy Markdown

Rsdoctor Bundle Diff Analysis

📊 Quick Summary
Project Total Size Gzip Size Change Gzip Change
bundle-diff 533.8 KB 173.0 KB 0 0

Generated by Rsdoctor GitHub Action

UltraModern Debug and others added 9 commits October 29, 2026 12:48
…rver and client

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nt aliases win over React externals

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…oth runtimes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ration stream

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…th on macOS

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@BleedingDev
BleedingDev force-pushed the feat/redact-default-20261028 branch from 1a5f4e6 to c3cce8a Compare October 29, 2026 12:07
UltraModern Debug and others added 3 commits October 29, 2026 13:25
…-redact sidecar

app-tools now declares `@tanstack/redact` as the exact npm alias
`npm:@bleedingdev/tanstack-redact@0.2.1`, the signed publish of the
reviewed patch. The repository exempts that exact owned version from the
24-hour release-age gate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the alias in source, upstream `@tanstack/redact` is rejected on every
staging and publish path. The CI-only rewrite to the reconstructed sidecar
and its qualification-only consumer bypass are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lient-rendered boundaries

The aliased runtime resolves under its physical @bleedingdev/tanstack-redact
directory. A remote that fails before the first read now lands inline as a
client-rendered boundary marker instead of a late <template> instruction.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@BleedingDev
BleedingDev force-pushed the feat/redact-default-20261028 branch from 3a03d5d to 925c56b Compare October 29, 2026 12:26
A finished compile emits its hot update even when a later edit supersedes
it before publication, or when Rsbuild never hands it to an aggregate
callback. A runtime that applies that update addresses the compile's
immutable graph directory, so its first lazy import answered 404. Each
compiler now records its finished graph in its done hook, before Rspack can
drop the compilation, and every publication pass retains those graphs
within the existing budget.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@BleedingDev
BleedingDev merged commit 8d81276 into main-ultramodern Oct 29, 2026
70 checks passed
@BleedingDev
BleedingDev deleted the feat/redact-default-20261028 branch October 29, 2026 13:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant