Skip to content

feat(Worklets): experimental bytecode worklets in legacy eval mode#9705

Merged
tjzel merged 12 commits into
mainfrom
@tjzel/worklets/bytecode-eval
Jul 8, 2026
Merged

feat(Worklets): experimental bytecode worklets in legacy eval mode#9705
tjzel merged 12 commits into
mainfrom
@tjzel/worklets/bytecode-eval

Conversation

@tjzel

@tjzel tjzel commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adding an optional opt-in behavior for Legacy Eval Mode to use bytecode instead of plain code for worklets in production.

This is a workaround for the Hermes V1 memory issue #9650

Mode Bundle Legacy Eval (code) Legacy Eval (bytecode)
Production bytecode bundle size
(Fabric Example)
6.5M 6.6M 9.4M

Docs for this feature will be added in a separate PR.

Test plan

App runs in Bundle Mode, Legacy Eval Mode (code) and Legacy Eval Mode (bytecode). To toggle bytecode, you must add hermesBytecode:true to babel.config.js in babel.config.js and also pass the getHBCBinary function.

@tjzel tjzel marked this pull request as ready for review June 25, 2026 14:07
@tjzel tjzel requested review from Copilot and tshmieldev June 25, 2026 14:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces an experimental, opt-in path for Legacy Eval Mode to ship Hermes bytecode (instead of source strings) for worklets in production, aiming to mitigate the Hermes V1 memory regression referenced in #9650.

Changes:

  • Add Babel plugin support to optionally compile worklets to Hermes bytecode in release builds (hermesBytecode + getHBCBinary) and embed it into __initData.
  • Extend the runtime (JS + C++) to evaluate embedded bytecode (evalBytecode) and to install unpackers from either code or bytecode.
  • Add/adjust Jest coverage and snapshots for the new wrapping/bytecode behavior; update example app configuration and an “About” indicator.

Reviewed changes

Copilot reviewed 19 out of 22 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
scripts/patches/fabric-example-babel-config.patch Updates bundleMode toggle patch context for the fabric example babel config.
packages/react-native-worklets/src/WorkletsModule/workletsModuleProxy.ts Renames the code unpacker loader method and adds a bytecode loader method to the proxy interface.
packages/react-native-worklets/src/WorkletsModule/NativeWorklets.native.ts Installs unpackers via code or bytecode based on __initData contents.
packages/react-native-worklets/src/types.ts Makes __initData.code optional and adds optional __initData.bytecode.
packages/react-native-worklets/src/memory/valueUnpacker.native.ts Adds bytecode evaluation path (evalBytecode) and adjusts eval usage to match new code wrapping.
packages/react-native-worklets/plugin/src/workletStringCode.ts Wrapes emitted worklet code as an expression (( … )) so evaluators return a function value.
packages/react-native-worklets/plugin/src/workletFactory.ts Adds bytecode emission pipeline and embeds bytecode (as Uint8Array(...).buffer) into init data.
packages/react-native-worklets/plugin/src/options.ts Documents new experimental plugin options.
packages/react-native-worklets/plugin/src/hermesBytecode.ts New helper that calls hermesc to compile a worklet string to bytecode with fallbacks/warnings.
packages/react-native-worklets/plugin/index.js Updates built plugin output to include bytecode compilation and wrapped code strings.
packages/react-native-worklets/plugin/index.d.ts Exposes new experimental plugin options in type definitions.
packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletHermesRuntime.cpp Adds global evalBytecode host function in release builds for Hermes worklet runtime.
packages/react-native-worklets/Common/cpp/worklets/Tools/ScriptBuffer.h Adds BytecodeBuffer to pass Hermes bytecode to evaluateJavaScript.
packages/react-native-worklets/Common/cpp/worklets/SharedItems/UnpackerLoader.h Refactors unpacker loading/installation to support both code and bytecode variants.
packages/react-native-worklets/Common/cpp/worklets/NativeModules/JSIWorkletsModuleProxy.cpp Splits unpacker loading into two JSI methods: code vs bytecode, with new argument shapes.
packages/react-native-worklets/tests/plugin.test.ts Updates regex expectations to match newly wrapped worklet code strings.
packages/react-native-worklets/tests/plugin-hermesBytecode.test.ts New tests validating bytecode emission + fallbacks using a mocked execFileSync.
packages/react-native-worklets/tests/snapshots/plugin-shared.test.ts.snap Snapshot updates reflecting wrapped initData code and changed hashes.
packages/react-native-worklets/tests/snapshots/plugin-bundleMode.test.ts.snap Snapshot updates reflecting hash changes in bundleMode outputs.
apps/fabric-example/babel.config.js Adds hermesBytecode and getHBCBinary wiring for the example app’s plugin config.
apps/common-app/src/apps/reanimated/examples/AboutExample.tsx Displays whether Legacy Eval bytecode is present via __initData.bytecode.
Files not reviewed (1)
  • packages/react-native-worklets/plugin/index.js: Generated file
Comments suppressed due to low confidence (1)

packages/react-native-worklets/Common/cpp/worklets/WorkletRuntime/WorkletHermesRuntime.cpp:8

  • std::vector is used in this file but there is no direct #include <vector>. Relying on transitive includes is brittle and can break with upstream header changes; include <vector> explicitly here.
#include <worklets/Tools/ScriptBuffer.h>
#include <worklets/WorkletRuntime/WorkletHermesRuntime.h>

#include <jsi/jsi.h>

#include <memory>
#include <string>
#include <utility>

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/react-native-worklets/plugin/src/options.ts Outdated

@tshmieldev tshmieldev left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks good

Comment thread packages/react-native-worklets/plugin/src/hermesBytecode.ts Outdated
@tjzel tjzel added this pull request to the merge queue Jul 8, 2026
Merged via the queue into main with commit 25aa993 Jul 8, 2026
20 checks passed
@tjzel tjzel deleted the @tjzel/worklets/bytecode-eval branch July 8, 2026 07:33
pull Bot pushed a commit to BasixKOR/react-native-reanimated that referenced this pull request Jul 8, 2026
## Summary

Adding docs for using bytecode in production for legacy eval mode software-mansion#9705.

## Test plan

🚀
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