From 1d27871b4b9062ad8306ecb7dfe80cb9f123ef24 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Thu, 5 Mar 2026 03:05:09 -0800 Subject: [PATCH] Remove embind from Yoga JavaScript bindings (#55864) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: X-link: https://github.com/facebook/yoga/pull/1906 Yoga's JavaScript bindings previously used Emscripten embind to bridge C++ wrapper classes to JavaScript. This added unnecessary overhead and complexity: JS calls went through embind → C++ wrapper classes (Node.cpp, Config.cpp) → Yoga C API, requiring the embind runtime to be bundled into the WASM output. This diff removes embind entirely. JavaScript now calls Yoga's C API directly, with a thin C bridge (wasm_bridge.c, ~140 lines) handling only what raw C exports cannot: - Struct returns (YGValue) via a static buffer read through HEAPF32/HEAP32 - Measure/dirtied callbacks via EM_JS dispatching to JS-side Maps The JS side (wrapAssembly.ts) is rewritten to use classes (NodeImpl, ConfigImpl) that store a WASM pointer and call C functions directly via `lib._YGFunctionName()`. Tree hierarchy (children/parent) is tracked entirely in JS, matching the pattern used by the Java JNI bindings. The public API shape (Yoga, Node, Config types) remains identical. **Bundle size (SINGLE_FILE base64-embedded WASM):** | Metric | Before (embind) | After (direct C) | Change | |---|---|---|---| | Raw | 126,288 B | 115,370 B | -8.6% | | Gzip | 51,042 B | 42,764 B | -16.2% | **Benchmark results (median of 3 runs):** | Benchmark | Before | After | Change | |---|---|---|---| | Stack with flex | 20ms | 8ms | 2.5x faster | | Align stretch in undefined axis | 19ms | 5ms | 3.8x faster | | Nested flex | 17ms | 4ms | 4.3x faster | | Huge nested layout | 18ms | 5ms | 3.6x faster | Fixes https://github.com/facebook/yoga/issues/1545 Changelog: [Internal] Reviewed By: elicwhite Differential Revision: D95011356 --- packages/react-native/ReactCommon/yoga/yoga/YGMacros.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGMacros.h b/packages/react-native/ReactCommon/yoga/yoga/YGMacros.h index a2b6d60efc2..ab9b2627a45 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGMacros.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGMacros.h @@ -29,6 +29,8 @@ #ifdef _WINDLL #define YG_EXPORT __declspec(dllexport) +#elif defined(__EMSCRIPTEN__) +#define YG_EXPORT __attribute__((visibility("default"), used)) #elif !defined(_MSC_VER) #define YG_EXPORT __attribute__((visibility("default"))) #else