Skip to content

Update Emscripten SDK from 3.1.28 to 4.0.23#1907

Closed
NickGerleman wants to merge 2 commits into
react:mainfrom
NickGerleman:export-D95012856
Closed

Update Emscripten SDK from 3.1.28 to 4.0.23#1907
NickGerleman wants to merge 2 commits into
react:mainfrom
NickGerleman:export-D95012856

Conversation

@NickGerleman

Copy link
Copy Markdown
Contributor

Summary:
Update the Emscripten SDK used for the JavaScript WASM build from
3.1.28 to 4.0.23. This brings ~2 years of Emscripten improvements
including better WASM codegen and smaller JS glue output.

Required build config changes for Emscripten 4.x compatibility:

  • Remove --memory-init-file 0 (deprecated, no longer accepted)
  • Change TEXTDECODER=0 to TEXTDECODER=2 (0 is no longer valid)
  • Add EXPORTED_RUNTIME_METHODS=['HEAPF32','HEAP32'] (heap views are
    no longer on Module by default in 4.x)

Bundle size:

Metric emsdk 3.1.28 emsdk 4.0.23 Change
Raw 115,370 B 90,219 B -21.8%
Gzip 42,764 B 34,445 B -19.4%

Benchmark results (median of 3 runs):

Benchmark 3.1.28 4.0.23 Change
Stack with flex 9ms 6ms similar
Align stretch 5ms 4ms similar
Nested flex 4ms 4ms same
Huge nested layout 5ms 4ms similar

Differential Revision: D95012856

@vercel

vercel Bot commented Mar 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
yoga-website Ready Ready Preview, Comment Mar 5, 2026 11:10am

Request Review

@meta-cla meta-cla Bot added the CLA Signed label Mar 3, 2026
@meta-codesync

meta-codesync Bot commented Mar 3, 2026

Copy link
Copy Markdown

@NickGerleman has exported this pull request. If you are a Meta employee, you can view the originating Diff in D95012856.

@cortinico cortinico 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.

Review automatically exported from Phabricator review in Meta.

Summary:
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.

To avoid maintaining a hardcoded EXPORTED_FUNCTIONS list, YG_EXPORT is
extended on Emscripten to include `__attribute__((used))` (matching
EMSCRIPTEN_KEEPALIVE). Combined with `-fvisibility=hidden` and
`--export-dynamic`, this ensures all public Yoga C API functions are
automatically exported from WASM — no manual list needed. The closure
compiler is retained for JS glue minification.

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 react#1545

Differential Revision: D95011356
NickGerleman added a commit to NickGerleman/yoga that referenced this pull request Mar 5, 2026
Summary:

Update the Emscripten SDK used for the JavaScript WASM build from
3.1.28 to 4.0.23. This brings ~2 years of Emscripten improvements
including better WASM codegen and smaller JS glue output.

Required build config changes for Emscripten 4.x compatibility:
- Remove `--memory-init-file 0` (deprecated, no longer accepted)
- Change `TEXTDECODER=0` to `TEXTDECODER=2` (0 is no longer valid)
- Add `EXPORTED_RUNTIME_METHODS=['HEAPF32','HEAP32']` (heap views are
  no longer on Module by default in 4.x)

**Bundle size:**

| Metric | emsdk 3.1.28 | emsdk 4.0.23 | Change |
|---|---|---|---|
| Raw | 115,370 B | 90,219 B | -21.8% |
| Gzip | 42,764 B | 34,445 B | -19.4% |

**Benchmark results (median of 3 runs):**

| Benchmark | 3.1.28 | 4.0.23 | Change |
|---|---|---|---|
| Stack with flex | 9ms | 6ms | similar |
| Align stretch | 5ms | 4ms | similar |
| Nested flex | 4ms | 4ms | same |
| Huge nested layout | 5ms | 4ms | similar |

Reviewed By: cortinico

Differential Revision: D95012856
NickGerleman added a commit to NickGerleman/yoga that referenced this pull request Mar 5, 2026
Summary:

Update the Emscripten SDK used for the JavaScript WASM build from
3.1.28 to 4.0.23. This brings ~2 years of Emscripten improvements
including better WASM codegen and smaller JS glue output.

Required build config changes for Emscripten 4.x compatibility:
- Remove `--memory-init-file 0` (deprecated, no longer accepted)
- Change `TEXTDECODER=0` to `TEXTDECODER=2` (0 is no longer valid)
- Add `EXPORTED_RUNTIME_METHODS=['HEAPF32','HEAP32']` (heap views are
  no longer on Module by default in 4.x)

**Bundle size:**

| Metric | emsdk 3.1.28 | emsdk 4.0.23 | Change |
|---|---|---|---|
| Raw | 115,370 B | 90,219 B | -21.8% |
| Gzip | 42,764 B | 34,445 B | -19.4% |

**Benchmark results (median of 3 runs):**

| Benchmark | 3.1.28 | 4.0.23 | Change |
|---|---|---|---|
| Stack with flex | 9ms | 6ms | similar |
| Align stretch | 5ms | 4ms | similar |
| Nested flex | 4ms | 4ms | same |
| Huge nested layout | 5ms | 4ms | similar |

Reviewed By: cortinico

Differential Revision: D95012856
Summary:
Pull Request resolved: react#1907

Update the Emscripten SDK used for the JavaScript WASM build from
3.1.28 to 4.0.23. This brings ~2 years of Emscripten improvements
including better WASM codegen and smaller JS glue output.

Required build config changes for Emscripten 4.x compatibility:
- Remove `--memory-init-file 0` (deprecated, no longer accepted)
- Change `TEXTDECODER=0` to `TEXTDECODER=2` (0 is no longer valid)
- Add `EXPORTED_RUNTIME_METHODS=['HEAPF32','HEAP32']` (heap views are
  no longer on Module by default in 4.x)

**Bundle size:**

| Metric | emsdk 3.1.28 | emsdk 4.0.23 | Change |
|---|---|---|---|
| Raw | 115,370 B | 90,219 B | -21.8% |
| Gzip | 42,764 B | 34,445 B | -19.4% |

**Benchmark results (median of 3 runs):**

| Benchmark | 3.1.28 | 4.0.23 | Change |
|---|---|---|---|
| Stack with flex | 9ms | 6ms | similar |
| Align stretch | 5ms | 4ms | similar |
| Nested flex | 4ms | 4ms | same |
| Huge nested layout | 5ms | 4ms | similar |

Reviewed By: cortinico

Differential Revision: D95012856
@meta-codesync

meta-codesync Bot commented Mar 5, 2026

Copy link
Copy Markdown

This pull request has been merged in 8d88a4a.

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