Skip to content

Add RSC Sandboxes#8300

Merged
rickhanlonii merged 14 commits intoreactjs:mainfrom
rickhanlonii:rsc-sandbox
Feb 28, 2026
Merged

Add RSC Sandboxes#8300
rickhanlonii merged 14 commits intoreactjs:mainfrom
rickhanlonii:rsc-sandbox

Conversation

@rickhanlonii
Copy link
Member

@rickhanlonii rickhanlonii commented Feb 11, 2026

Overview

Adds browser-only <SandpackRSC> component for RSC sandboxes.

This uses the browser version of react-server-dom-webpack to run RSCs in a web worker, so there's no custom sandpack bundler. In the worker, we use sucrase to transpile JSX and then send it back to the client.

It currently does not support opening it in an external sandbox, but we can set that up with a new custom template (might need help from the sandpack folks).

@rickhanlonii
Copy link
Member Author

cc @lubieowoce @gaearon

@github-actions
Copy link

github-actions bot commented Feb 11, 2026

Size changes

Details

📦 Next.js Bundle Analysis for react-dev

This analysis was generated by the Next.js Bundle Analysis action. 🤖

⚠️ Global Bundle Size Increased

Page Size (compressed)
global 115.14 KB (🟡 +50 B)
Details

The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!

Five Pages Changed Size

The following pages changed size from the code in this PR compared to its base branch:

Page Size (compressed) First Load
/404 126.49 KB (🟡 +108 B) 241.63 KB
/500 126.5 KB (🟡 +108 B) 241.63 KB
/[[...markdownPath]] 128.93 KB (🟡 +108 B) 244.07 KB
/errors 126.74 KB (🟡 +108 B) 241.88 KB
/errors/[errorCode] 126.71 KB (🟡 +108 B) 241.85 KB
Details

Only the gzipped size is provided here based on an expert tip.

First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

Next to the size is how much the size has increased or decreased compared with the base branch of this PR. If this percentage has increased by 10% or more, there will be a red status indicator applied, indicating that special attention should be given to this.

@gaearon
Copy link
Member

gaearon commented Feb 11, 2026

you might find https://github.com/gaearon/rscexplorer helpful, I'm relatively sure it works correctly but it has a bunch of stuff you don't need

@rickhanlonii
Copy link
Member Author

thanks @gaearon yeah i gave that to claude as a reference as well as @lubieowoce's branch

Copy link
Member

@eps1lon eps1lon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super exciting to get these going.

/learn/rsc-sandbox-test produces a 404 when deployed. Works locally though.

I think something fucky is happening

What's that referring to?

does this stream? can it?

It does the way you structured it now. Each Flight chunk is sent separately with postMessage which is the streaming way on the Server. It wouldn't stream if you'd accumulate all chunks before sending them. The Client puts the chunks into a stream as well that's passed to the Client for decoding before all chunks have. So the Client is streaming as well.

Editing sandboxes can get into a broken state

Seems fine from my random testing locally.

Comment on lines 317 to 321
After modifying `worker-server.source.js` or `webpack-shim.source.js`:

```bash
node scripts/buildRscWorker.mjs
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do this in CI to validate this has been done? Pretty easy to forget otherwise.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it will automatically run on yarn build

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add a CI check for it, but not sure if it's worth running a CI check on every diff for somthing that will in all likelyhood almost never need to run again?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worker-server.source is a product of rsc-server? There's plenty of things we might change there. Definitely for when we showcase console replaying.

Comment on lines 433 to 435
var msg = err && err.message ? err.message : String(err);
var stack = err && err.stack ? err.stack : '';
console.error('[RSC Server Error]', msg, stack);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var msg = err && err.message ? err.message : String(err);
var stack = err && err.stack ? err.stack : '';
console.error('[RSC Server Error]', msg, stack);
console.error('[RSC Server Error]', err);

That way browsers can display the error correctly (including other properties like cause) while ensuring ignore-listing works.

There are more places that needlessly dissect the error instead of logging it as-is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated on the server, on the client we need to access digest because the server is actually running the prod build. I tried to get it to run the client version, but I couldn't get it to work.

Screenshot 2026-02-28 at 11 11 09 AM

@rickhanlonii
Copy link
Member Author

@eps1lon thanks! rsc-sandbox-test is gated to DEV only.

The something fucky part is old, i don't remember what it was though

@rickhanlonii rickhanlonii changed the title [WIP] Add RSC Sandboxes Add RSC Sandboxes Feb 28, 2026
@rickhanlonii
Copy link
Member Author

OK feedback updates done, I think this is ready for final feedback

@eps1lon
Copy link
Member

eps1lon commented Feb 28, 2026

thanks! rsc-sandbox-test is gated to DEV only.

Gotcha, so we need an actual page where we demo it to test deploy behavior?

Copy link
Member

@eps1lon eps1lon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@rickhanlonii
Copy link
Member Author

Yeah, I confirmed it works in a preview deploy on an earlier commit before I made it dev-only.

I'll add it to an actual docs page next and we can confirm it works in that preview deploy too.

@rickhanlonii rickhanlonii merged commit 427f24d into reactjs:main Feb 28, 2026
6 checks passed
@rickhanlonii rickhanlonii deleted the rsc-sandbox branch February 28, 2026 18:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants