Support All of Structure Clone in RSC Serialization

This issue has been created since 2022-11-15.

The React Server Components payload is a custom protocol that extends what is serializable beyond just JSON. Beyond just JSON we also support all React primitives (React.lazy, ReactNode) and global named symbols (Symbol.for). We also already have plan to expand this support with these as well:

  • Promises
  • Typed Arrays / DataView
  • BigInt
  • undefined, Infinity, NaN, -0

We don't have plans to make this algorithm pluggable from the outside because we're concerned about the complexity this puts on the ecosystem and that components won't be reusable in different contexts where they're not configured or configurations are conflicting.

However, it might make sense to expand support to the types supported by the Structured clone algorithm which is already standardized and specified.

  • Cyclic references: We already support references in the protocol. This is mostly just an implementation detail for the perf cost whether something should be inlined as JSON or defined as a separate row.
  • ArrayBuffer: For Typed Arrays we might stick to using the underlying buffer coming from the stream instead of cloning the data. All values are considered immutable anyway. For ArrayBuffers we can't use that trick though so it would require a new clone of the data which might be a bit of a foot gun when switching between buffers and typed arrays.
  • Error objects: We already support thrown errors and we could support more errors in the encoding. However, we intentionally don't pass them through with all information. We cover them up with digests since the error message and stack can sometimes include sensitive information that only the server should have access to. We would likely have to do the same here.
  • Boolean/String objects: We don't currently support the object wrappers around primitives e.g. new String(). You're not really supposed to use these in modern JS so it's kind of annoying to have to add extra code to handle this case.
  • RegExp: These are pretty straightforward but can possibly have security implications.
  • Date, Map, Set: These are fairly straightforward to serialize so it's mostly a matter of allowing these as special cases. Why are these special? Because Structured Clone says so.
  • (Temporal: It seems appropriate that this would be added to structured clone but we need to confirm.)

We probably won't support Web specific APIs that don't necessarily have an equivalent on the Server or isn't directly transferrable such as if it has handles to local hardware or file system resources. The only one that might be easy to support:

  • Blob: This would just be a wrapper around the raw buffer from the stream same as Typed Arrays. I don't think any servers really support this yet though so it would only once that's the case.
KATT wrote this answer on 2022-11-15

I really appreciate that you're thinking about structures outside of the default JSON-stuff.

Maybe there's a world where React itself doesn't do the heavy lifting, but you instead allow developers to add their own serialization libraries?

There's devalue, superjson, and others that can do a lot more than the built-in limitations of JSON.stringify/JSON.parse()

I for one would love to be able to use BigInt & Temporal polyfills for date objects (which I both currently can use with superjson together with tRPC).

sebmarkbage wrote this answer on 2022-11-15

The serialization algorithm itself is most of what the RSC server is and it has a lot of special features as part of that. So it's not as easily pluggable.

Another consideration is that for static types to be preserved, it needs to get the same type on both sides. E.g. toJSON() is not supported even though it's supported in JSON.stringify because that changes the type on the receiving side.

It's also important to us that code is interchangeable between projects and that npm packages are able to support. It's easy for a plug-in system to go out of control.

That said, we already support or want to support most things that those other libraries support, so if you have specific examples it would be good to add to the list.

It seems likely that Temporal would soon be added to structured clone, but it would be good to get that confirmed and that there's no blockers to doing so in the web spec.

KATT wrote this answer on 2022-11-15

For me, it's all about getting static types to be preserved and used interchangeably across the HTTP boundary.

Ideally, I'd like to be able to have some sort of mapper where I can interpret any sort of object and serialize/deserialize according to my own preference since that allows me to statically type an object and "know" its integrity will remain the same throughout the serialization.

I don't think React itself should be the gatekeeper or responsible for what data types can or cannot be serialized.

I do see how something like supporting promises will make this hard as this seems very specific to the RSC implementation, but I don't think opening this up would impede the use of making code interchangeable across projects - most likely, any open-source project would not depend on a special type.

sophiebits wrote this answer on 2022-12-05

RegExp: These are pretty straightforward but can possibly have security implications.

What's the security risk here?

More Details About Repo
Owner Name facebook
Repo Name react
Full Name facebook/react
Language JavaScript
Created Date 2013-05-24
Updated Date 2022-12-10
Star Count 198882
Watcher Count 6638
Fork Count 41302
Issue Count 1120

YOU MAY BE INTERESTED

Issue Title Created Date Comment Count Updated Date
TypeError("Cannot call select_related() after .values() or .values_list()") 1 2022-01-05 2022-12-09
版本:v0.1.5.6升级版本:v0.1.5.8后 无法启动bot,提示插件冲突 截了最后一小段打印信息 5 2022-05-29 2022-12-04
ezTable fixed height 4 2021-01-02 2022-06-29
bug: error 400 (bad request) using NodeJS SDK method `unregisterCallback` 0 2022-11-24 2022-11-29
Add the ability to set instance_termination_action to DELETE for Spot VMs 0 2022-08-20 2022-11-19
Just curious how do you set the horizontal line to split windows 2 2022-09-08 2022-11-29
Maximizing receive throughput for single listener 2 2022-08-21 2022-10-22
[BUG] bytes lost (byteRcvLoss) reporting in stats is broken in 1.5.0 1 2022-07-23 2022-10-22
Unable to load DLL avformat.58 2 2021-12-27 2022-11-06
Unable to close websocket from the on_message handler 0 2021-12-25 2022-12-01
Supports Dart& Flutter now! 5 2021-03-08 2022-12-09
What is the status of support for deconvolution in TensorFlow and PyTorch 4 2022-11-18 2022-11-27
OS kill signal does not save tabs. 7 2017-03-01 2022-10-20
week start is set to process start for instance activity api endpoint 0 2022-08-28 2022-12-04
Provide a `\hrefstyle` acting on `\href`, similar to `\urlstyle` 2 2021-07-05 2022-11-29
non-Latin characters, non-BMP characters, symbols missing 13 2021-05-26 2022-11-11
Fall and step sounds are played multiple times for players in some cases 2 2021-09-11 2022-10-24
Please verify that the package.json has a valid "main" entry 1 2021-03-21 2022-12-04
`Duration` and `Instant` should live in `bevy_time`, not `bevy_utils` 5 2022-09-19 2022-09-27
jsonTypes false positive with array path and extra keys 1 2020-03-24 2022-11-19
FunctionNames readability check does not recognize an acronym when followed by a symbol 0 2022-08-25 2022-11-25
Error generating windows package 2 2022-03-17 2022-11-13
Remove legacy vector style encoding 0 2022-06-07 2022-06-30
Is it possible to use a custom base URL for custom endpoints? 2 2022-09-26 2022-12-02
Delete and Edit client notes 1 2021-09-16 2022-10-31
Allow Rosetta users to edit native block menu 4 2021-12-29 2022-11-29
Resolver error occurs when use custom OpenApiCustomiser to GroupedOpenApi 2 2022-02-07 2022-11-22
Knative 1-click application 1 2022-03-08 2022-11-20
Tweak currency placement in the price fields 3 2022-10-19 2022-10-24
[Bug] EditText not visible if "focus 'type in answer'" and fullscreen: "hide system bars" 4 2021-10-22 2022-12-02
Logo image for light theme 2 2021-10-06 2022-07-14
custom elements 0 2021-09-27 2022-01-04
REQUIRED process [config_parser-2] has died! 15 2021-05-05 2022-11-23
drivers: wifi: eswifi: Offload sockets accessing invalid net_context, resulting in errors in FLASH_SR and blocking flash use 1 2022-11-17 2022-11-12
Don't keep duplicate entries in history file 13 2022-09-06 2022-10-13
Xamarin.Forms.Visual.Material paths too long when doing iOS archiving with Visual Studio 2022 1 2022-05-10 2022-10-02
PHP 8 support + archive module 0 2021-11-15 2021-12-26
Bonsai Integration Questions 0 2020-06-04 2022-10-21
Several features to improve compatibility with pidantic 3 2022-04-23 2022-10-27
How to split a live audio stream? 0 2022-06-13 2022-11-19
ordered is part of the Meta of a schema 0 2021-09-23 2022-11-22
[Event Request] codeunit 80 "Sales-Post" OnBeforePostItemJnlLine 2 2022-05-23 2022-12-05
Error in `python': double free or corruption | During training 3 2021-10-20 2022-10-13
Loading the trained model predicts different results than using test.py 2 2021-11-21 2022-10-20
cmd/compile: avoid allocations for some return values 3 2017-09-28 2022-09-15
[Question]: 使用uie官方实例代码时报错,无结果返回 1 2022-11-26 2022-12-04
tcpip/stack: (*nic).DeliverNetworkPacket godoc out of date 0 2022-01-21 2022-11-14
Cleanup HTTP artifacts after a successful CF push 0 2018-10-31 2022-12-10
Incorrect result format for queries with single value filters and GROUPING SET on the same dimension 3 2022-10-10 2022-11-01
Spring data cassandra must introduce enabled flag 1 2022-03-11 2022-11-24