Skip to content

Add ArrayBuffer and Uint8Array support to C++ TurboModules#56001

Open
hsjoberg wants to merge 6 commits intofacebook:mainfrom
hsjoberg:codegen-uint8array-and-arraybuffer
Open

Add ArrayBuffer and Uint8Array support to C++ TurboModules#56001
hsjoberg wants to merge 6 commits intofacebook:mainfrom
hsjoberg:codegen-uint8array-and-arraybuffer

Conversation

@hsjoberg
Copy link
Contributor

@hsjoberg hsjoberg commented Mar 9, 2026

Summary:

Hi. This pull request adds support for ArrayBuffer and Uint8Array to C++ TurboModules.

This is useful for native modules that need to pass raw byte data back and forth, where the alternative would otherwise be base64 encoding or other suboptimal solutions.

ArrayBuffer support uses the existing JSI type directly, so C++ module methods can accept and return jsi::ArrayBuffer.

Uint8Array support adds a new C++ helper class, facebook::react::Uint8Array, together with bridging logic:

  • JS -> native: borrowed zero-copy over the JS-backed bytes
  • native -> JS: copy from owned native bytes when using std::vector<uint8_t>, or zero-copy when backed by jsi::MutableBuffer

Note: zero-copy JS -> native does not use MutableBuffer, as Hermes API changes such as facebook/hermes#1733 would need to land first. Lib authors are expected to copy data if they need the bytes to outlive the synchronous call or use them off-thread.
If reviewers prefer, this can instead be changed to use memcpy in the bridging path.

This PR intentionally only focuses on C++ TurboModules, as I think this is a good starting point. It also keeps the scope lower.
Java/Kotlin and ObjC support can be followed up later.

Changelog:

[GENERAL] [ADDED] - Add ArrayBuffer and Uint8Array support to C++ TurboModules

Test Plan:

I added and tested ArrayBuffer and Uint8Array in RNTester via NativeCxxModuleExample.

There are parser/codegen tests for the new reserved types.

I have written C++ unit tests, but I can't find targets for C++ tests in React Native OSS.

I also tested Uint8Array support in my own lib.

Usage examples

// Copied Uint8Array:
facebook::react::Uint8Array copied(std::vector<uint8_t>{0xDE, 0xAD, 0xBE, 0xEF});

// Zero-copy Uint8Array via MutableBuffer:
class VectorMutableBuffer final : public jsi::MutableBuffer {
public:
  explicit VectorMutableBuffer(std::vector<uint8_t> bytes) : bytes_(std::move(bytes)) {}

  size_t size() const override { return bytes_.size(); }
  uint8_t* data() override { return bytes_.data(); }

private:
  std::vector<uint8_t> bytes_;
};

facebook::react::Uint8Array zeroCopy(
  std::make_shared<VectorMutableBuffer>(std::vector<uint8_t>{0xDE, 0xAD, 0xBE, 0xEF})
);

// Copy an incoming Uint8Array:
auto owned = input.toOwned();

// ArrayBuffer backed by MutableBuffer.
// Alternatively, invoke the JS ArrayBuffer constructor through JSI.
auto buffer = std::make_shared<VectorMutableBuffer>(std::vector<uint8_t>{0xDE, 0xAD, 0xBE, 0xEF});
jsi::ArrayBuffer arrayBuffer(rt, buffer);

@meta-cla meta-cla bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Mar 9, 2026
@facebook-github-bot facebook-github-bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Mar 9, 2026
@hsjoberg hsjoberg force-pushed the codegen-uint8array-and-arraybuffer branch from 144b1ca to bff2e89 Compare March 9, 2026 16:08
@hsjoberg hsjoberg force-pushed the codegen-uint8array-and-arraybuffer branch from bff2e89 to 7f25de4 Compare March 9, 2026 19:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants