Skip to content

[Flight] Standardize ClientReferenceMetadata tuple type#36197

Draft
unstubbable wants to merge 1 commit intofacebook:mainfrom
unstubbable:standardize-client-reference-metadata
Draft

[Flight] Standardize ClientReferenceMetadata tuple type#36197
unstubbable wants to merge 1 commit intofacebook:mainfrom
unstubbable:standardize-client-reference-metadata

Conversation

@unstubbable
Copy link
Copy Markdown
Collaborator

Previously, ClientReferenceMetadata was declared as an opaque type in the Flight server config (ReactFlightServerConfigBundlerCustom.js), with each bundler defining its own tuple shape. Webpack, Turbopack, and Unbundled used [id, chunks, name, async?] while Parcel used [id, name, bundles, importMap?], placing the chunks array at different indices. This made it impossible for ReactFlightServer.js to access the chunks array without bundler-specific accessor functions.

This change standardizes all bundlers on a common shape where id is at index 0, name is at index 1, and chunks is at index 2. A bundler- specific extra like the async flag or Parcel's importMap can go at index 3. The ClientReferenceMetadata type is changed from an opaque type to a concrete union type, so ReactFlightServer.js can now directly access metadata[2] to get the chunks array with proper Flow typing.

This only affects the internal wire format tuple, not the ClientManifest that frameworks pass into Flight. The manifest entry shape ({id, chunks, name, async?}) remains unchanged.

The motivation is to enable deduplicating individual chunk URLs across client references in the RSC stream. With a known, non-opaque type, emitImportChunk can extract, deduplicate, and replace chunk entries without needing bundler-specific callback functions or accessor methods.

@meta-cla meta-cla bot added the CLA Signed label Apr 2, 2026
@github-actions github-actions bot added the React Core Team Opened by a member of the React Core Team label Apr 2, 2026
@react-sizebot
Copy link
Copy Markdown

react-sizebot commented Apr 2, 2026

Comparing: 1b45e24...af24e98

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.js = 6.84 kB 6.84 kB +0.05% 1.88 kB 1.88 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 612.91 kB 612.91 kB = 108.30 kB 108.30 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.84 kB 6.84 kB = 1.88 kB 1.88 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js = 678.85 kB 678.85 kB = 119.27 kB 119.27 kB
facebook-www/ReactDOM-prod.classic.js = 698.24 kB 698.24 kB = 122.65 kB 122.65 kB
facebook-www/ReactDOM-prod.modern.js = 688.55 kB 688.55 kB = 121.03 kB 121.03 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
oss-experimental/react-noop-renderer/cjs/react-noop-renderer-flight-client.production.js +0.58% 2.23 kB 2.24 kB +0.84% 0.84 kB 0.84 kB
oss-stable-semver/react-noop-renderer/cjs/react-noop-renderer-flight-client.production.js +0.58% 2.23 kB 2.24 kB +0.84% 0.84 kB 0.84 kB
oss-stable/react-noop-renderer/cjs/react-noop-renderer-flight-client.production.js +0.58% 2.23 kB 2.24 kB +0.84% 0.84 kB 0.84 kB
oss-experimental/react-noop-renderer/cjs/react-noop-renderer-flight-client.development.js +0.44% 2.99 kB 3.00 kB +0.67% 1.05 kB 1.06 kB
oss-stable-semver/react-noop-renderer/cjs/react-noop-renderer-flight-client.development.js +0.44% 2.99 kB 3.00 kB +0.67% 1.05 kB 1.06 kB
oss-stable/react-noop-renderer/cjs/react-noop-renderer-flight-client.development.js +0.44% 2.99 kB 3.00 kB +0.67% 1.05 kB 1.06 kB
oss-experimental/react-noop-renderer/cjs/react-noop-renderer-flight-server.production.js +0.28% 2.49 kB 2.49 kB +0.85% 0.82 kB 0.83 kB
oss-stable-semver/react-noop-renderer/cjs/react-noop-renderer-flight-server.production.js +0.28% 2.49 kB 2.49 kB +0.85% 0.82 kB 0.83 kB
oss-stable/react-noop-renderer/cjs/react-noop-renderer-flight-server.production.js +0.28% 2.49 kB 2.49 kB +0.85% 0.82 kB 0.83 kB
oss-experimental/react-noop-renderer/cjs/react-noop-renderer-flight-server.development.js +0.22% 3.14 kB 3.15 kB +0.84% 0.95 kB 0.96 kB
oss-stable-semver/react-noop-renderer/cjs/react-noop-renderer-flight-server.development.js +0.22% 3.14 kB 3.15 kB +0.84% 0.95 kB 0.96 kB
oss-stable/react-noop-renderer/cjs/react-noop-renderer-flight-server.development.js +0.22% 3.14 kB 3.15 kB +0.84% 0.95 kB 0.96 kB

Generated by 🚫 dangerJS against af24e98

Previously, `ClientReferenceMetadata` was declared as an opaque type in
the Flight server config (`ReactFlightServerConfigBundlerCustom.js`),
with each bundler defining its own tuple shape. Webpack, Turbopack, and
Unbundled used `[id, chunks, name, async?]` while Parcel used `[id,
name, bundles, importMap?]`, placing the chunks array at different
indices. This made it impossible for `ReactFlightServer.js` to access
the chunks array without bundler-specific accessor functions.

This change standardizes all bundlers on a common shape where `id` is at
index 0, `name` is at index 1, and `chunks` is at index 2. A bundler-
specific extra like the async flag or Parcel's `importMap` can go at
index 3. The `ClientReferenceMetadata` type is changed from an opaque
type to a concrete union type, so `ReactFlightServer.js` can now
directly access `metadata[2]` to get the chunks array with proper Flow
typing.

This only affects the internal wire format tuple, not the
`ClientManifest` that frameworks pass into Flight. The manifest entry
shape (`{id, chunks, name, async?}`) remains unchanged.

The motivation is to enable deduplicating individual chunk URLs across
client references in the RSC stream. With a known, non-opaque type,
`emitImportChunk` can extract, deduplicate, and replace chunk entries
without needing bundler-specific callback functions or accessor methods.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed React Core Team Opened by a member of the React Core Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants