facebook/yoga
Yoga is an embeddable layout engine targeting web standards.
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 3w ago
- ✓33+ active contributors
- ✓Distributed ownership (top contributor 18% of recent commits)
Show 3 more →Show less
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/facebook/yoga)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/facebook/yoga on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: facebook/yoga
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/facebook/yoga shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 3w ago
- 33+ active contributors
- Distributed ownership (top contributor 18% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live facebook/yoga
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/facebook/yoga.
What it runs against: a local clone of facebook/yoga — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in facebook/yoga | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 48 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of facebook/yoga. If you don't
# have one yet, run these first:
#
# git clone https://github.com/facebook/yoga.git
# cd yoga
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of facebook/yoga and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "facebook/yoga(\\.git)?\\b" \\
&& ok "origin remote is facebook/yoga" \\
|| miss "origin remote is not facebook/yoga (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "yoga/YGNode.h" \\
&& ok "yoga/YGNode.h" \\
|| miss "missing critical file: yoga/YGNode.h"
test -f "yoga/Yoga.h" \\
&& ok "yoga/Yoga.h" \\
|| miss "missing critical file: yoga/Yoga.h"
test -f "yoga/algorithm/FlexLayout.cpp" \\
&& ok "yoga/algorithm/FlexLayout.cpp" \\
|| miss "missing critical file: yoga/algorithm/FlexLayout.cpp"
test -f "CMakeLists.txt" \\
&& ok "CMakeLists.txt" \\
|| miss "missing critical file: CMakeLists.txt"
test -f "gentest/src/CssToYoga.ts" \\
&& ok "gentest/src/CssToYoga.ts" \\
|| miss "missing critical file: gentest/src/CssToYoga.ts"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 48 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~18d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/facebook/yoga"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Yoga is a high-performance, embeddable flexbox layout engine written in C++20 that implements web-standard CSS Flexbox semantics. It targets multiple platforms (iOS, Android, Web, macOS) with language bindings in Java, TypeScript, Kotlin, Swift, and Objective-C, enabling React Native, React, and other frameworks to compute cross-platform layouts with pixel-perfect consistency. Monorepo with C++ core in yoga/generic/YGNode.cpp and yoga/generic/YGLayout.cpp, platform-specific bindings in java/com/facebook/yoga/ (JNI wrapper), csharp/, typescript/src/ for JavaScript, and swift/ for Apple. Benchmarks live in benchmark/Benchmark.cpp with real app captures (benchmark/captures/). The gentest/ pipeline auto-generates test fixtures from HTML specs rendered in Chrome to ensure standards compliance.
👥Who it's for
Mobile and cross-platform framework engineers at Meta (React Native), embedded systems developers, and layout library maintainers who need a lightweight, deterministic flexbox implementation that works across native and web platforms without depending on browser engines.
🌱Maturity & risk
Production-ready and actively maintained. Yoga powers React Native layouts across billions of devices, has comprehensive CI/CD pipelines (.github/workflows/*.yml validate C++, JS, Android, Swift, and tests), and maintains Maven Central/npm publishing. The codebase shows regular commits with generated test coverage from HTML fixtures. Risks: primarily single-maintainer from Meta, but backed by their infrastructure.
Low risk for core layout use cases, but consider: the C++ core is tightly coupled to specific React Native versions (Java and Kotlin bindings reflect Android dependency); generated tests from gentest/fixtures may lag real-world Flexbox edge cases; breaking API changes occasionally happen across major versions (check CHANGELOG). No external package dependencies shown, reducing supply-chain risk.
Active areas of work
Active development on TypeScript bindings (.ts files in repo), Android validation in CI/CD pipelines (.github/workflows/validate-android.yml), and regular npm/Maven Central releases (publish-*.yml workflows). Recent work likely includes refinements to Kotlin interop and web-standards alignment given the large TypeScript footprint (1.6M lines).
🚀Get running
git clone https://github.com/facebook/yoga.git
cd yoga
./unit_tests Release
# or for JS development:
yarn install
yarn gentest
Daily commands:
# C++ unit tests (debug or release):
./unit_tests Debug
# JavaScript tooling:
yarn install && yarn gentest
# Android (via gradle):
./gradlew build
# Benchmark:
./benchmark/benchmark
🗺️Map of the codebase
yoga/YGNode.h— Core node abstraction representing layout tree elements; fundamental to understanding Yoga's tree structure and propertiesyoga/Yoga.h— Public C API entry point; defines all public flexbox properties and functions that consumers depend onyoga/algorithm/FlexLayout.cpp— Main flexbox layout calculation engine; implements W3C flex algorithm and is the computational heart of the libraryCMakeLists.txt— Primary build configuration; orchestrates C++ compilation, bindings generation, and test execution across all platformsgentest/src/CssToYoga.ts— Converts CSS layout specs to Yoga test cases; bridges HTML fixtures to generated test code for all language bindingsyoga/algorithm/Calculate.cpp— Dimension calculation and constraint propagation; critical for resolving flex basis, sizing, and percentage-based layoutsenums.py— Single source of truth for all Yoga enumerations (Align, Justify, FlexDirection, etc.); used to auto-generate bindings for C#, Java, JavaScript, Swift
🧩Components & responsibilities
- YGNode tree (C++ linked list / vector structure) — In-memory representation of layout hierarchy; stores flex properties, computed layout (position, size), dirty state
- Failure mode: Memory leak if tree not manually freed; circular references in parent/child pointers
- FlexLayout algorithm (C++20 recursive function) — Implements W3C Flexbox spec item sizing, flex grow/shrink distribution, wrap, and cross-axis alignment
- Failure mode: Infinite loop if constraints unsatisfiable; numerical precision loss with deeply nested trees; cache invalidation bugs if dirty marking incorrect
- gentest fixture pipeline (TypeScript, Puppeteer, Chrome DevTools Protocol, code emitters) — Converts CSS test cases to expected Yoga layouts by rendering in Chrome; generates multi-language test code from single HTML source
- Failure mode: Chrome version mismatch causes layout divergence; slow test generation (minutes per fixture); em
🛠️How to make changes
Add a new flexbox property
- Add enum value to enums.py (e.g., new align or justify option) (
enums.py) - Add property field and getter/setter to YGNode class (
yoga/YGNode.h) - Implement property logic in Calculate.cpp or FlexLayout.cpp (
yoga/algorithm/Calculate.cpp) - Add C API functions to Yoga.h and Yoga.cpp (
yoga/Yoga.h) - Run gentest to auto-generate tests for all language bindings (
gentest/gentest-driver.ts)
Add a new test case from HTML fixture
- Create HTML fixture file in gentest/fixtures/ showing desired layout (
gentest/fixtures/YGNewFeatureTest.html) - Run gentest driver to render in Chrome and extract expected layout values (
gentest/gentest-driver.ts) - CssToYoga converts CSS to Yoga API calls; Emitters generate C++/Java/JS test code (
gentest/src/CssToYoga.ts) - Generated tests appear in build output and are run by unit_tests script (
CMakeLists.txt)
Support a new platform or language binding
- Create new Emitter subclass in gentest/src/emitters/ (
gentest/src/emitters/Emitter.ts) - Implement code generation logic by mapping enums and API calls to target language syntax (
gentest/src/emitters/CppEmitter.ts) - Add CMake build rule or gradle task to compile/publish the new binding (
CMakeLists.txt) - Add GitHub Actions workflow for platform-specific CI validation (
.github/workflows/validate-tests.yml)
🔧Why these technologies
- C++20 — Performance-critical layout calculations require compiled language; enables cross-platform portability without runtime overhead
- CMake — Manages complex multi-platform build (C++, Android NDK, Emscripten, Swift PM) from single configuration
- TypeScript + Chrome headless — Grounds test generation in W3C spec compliance by rendering fixtures in real browser engine; eliminates layout spec interpretation disagreements
- Code generation (enums.py, Emitters) — Keeps 6+ language bindings synchronized with core C++ changes; single enum source avoids binding drift
⚖️Trade-offs already made
-
HTML fixture → Chrome rendering → generated tests (not hand-written)
- Why: Ensures test suite always reflects W3C flexbox spec as implemented by Chromium; eliminates manual test bug sources
- Consequence: Setup complexity (Emscripten, Chrome pool) but pays off in test maintainability and spec alignment
-
Single C++ core with multiple language bindings via code generation
- Why: Avoids reimplementing layout algorithm in Java/JS/Swift; all platforms get identical behavior
- Consequence: Core engine cannot be quickly patched in one language; all bindings must be regenerated and published together
-
Embeddable, not a layout service (no daemon, no network)
- Why: Low latency and zero deployment overhead for mobile apps; library integrates directly into process
- Consequence: Cannot share layout cache across apps; each process maintains own node tree and caches
🚫Non-goals (don't propose these)
- Not a CSS parser or HTML renderer (accepts pre-built node trees from host app)
- Not a real-time layout server (no daemon or network API; synchronous tree manipulation only)
- Not a web browser; does not execute JavaScript, handle events, or manage reflows
- Not a replacement for native platform layout systems (complements them; used alongside platform boxes)
🪤Traps & gotchas
- Generated test code: tests in gentest/ are auto-generated from HTML fixtures via
yarn gentest—modifying test .cpp files directly will be overwritten. Always edit .html fixtures and regenerate. 2. C++ standard: requires C++20; older toolchains will fail silently. 3. JNI memory management: Java bindings (java/com/facebook/yoga/) hold native pointers; improper cleanup causes leaks—see YogaNode.finalize(). 4. Language binding drift: not all C++ features are exposed in all language bindings (e.g., some Android features may not exist in TypeScript)—check binding files before assuming API parity. 5. Benchmark captures are stale: benchmark/captures/*.json are snapshots; actual apps may have evolved; regenerate with real captures if testing against live React Native apps.
🏗️Architecture
💡Concepts to learn
- Flexbox layout algorithm (CSS Flexible Box Module) — Yoga implements the W3C Flexbox spec; understanding flex direction, justify-content, align-items, and flex-basis is essential to using this library correctly and debugging layout issues
- JNI (Java Native Interface) — Yoga's Java and Kotlin bindings use JNI to call C++ code; understanding memory ownership, reference counting, and the JNI boundary is critical when modifying java/com/facebook/yoga/ or debugging crashes
- Language bindings / FFI (Foreign Function Interface) — Yoga's core is C++20 but exposes APIs in 6+ languages; each binding (Java, TypeScript, Swift, Kotlin, Objective-C) translates user calls to C++ via wrapper patterns—understanding this pattern helps debug cross-language issues
- WebAssembly (WASM) — Yoga can be compiled to WASM via Emscripten (see .github/actions/cache-emsdk), enabling layout computation in browsers and Node.js; critical for web-based deployments of Yoga
- Test fixture generation from HTML — Yoga's gentest pipeline renders HTML in Chrome to auto-generate ground-truth layout tests; understanding this spec-driven testing approach (fixtures/ → yarn gentest → C++ tests) ensures new features stay standards-compliant
- Memory layout and cache locality — Yoga prioritizes performance for mobile UI rendering; understanding how YGNode stores flexbox state and how layout passes traverse the tree impacts optimization opportunities in benchmark/Benchmark.cpp
- Visitor pattern (tree traversal) — Yoga's layout computation uses tree traversal (flex, measure, layout passes); the visitor/recursive descent pattern appears throughout yoga/generic/YGNode.cpp and is key to understanding the algorithm flow
🔗Related repos
microsoft/layoutengine— Alternative CSS layout engine used in some embedded systems; less mature than Yoga but referenced in Flexbox researchgoogle/skia— Sibling rendering engine at same architectural level; Yoga computes layout, Skia renders the result in many frameworksfacebook/react-native— Primary consumer of Yoga; React Native's entire layout system delegates to this engine via JNI bindingsfacebook/react— Web sibling to React Native; can use Yoga bindings via TypeScript for layout computation in DOM-free contexts (e.g., canvas rendering)emscripten-core/emscripten— Used to compile Yoga to WebAssembly for browser/Node.js; .github/actions/cache-emsdk indicates active WASM build setup
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add Python bindings validation workflow in CI/CD
The repo has .github/workflows for C++, JS, Android, and SwiftPM validation, but no dedicated CI workflow for Python bindings. Given that enums.py exists at the root and the project supports multiple language bindings, adding a validate-python.yml workflow would ensure Python binding compatibility across releases and catch integration issues early.
- [ ] Create .github/workflows/validate-python.yml following the pattern of validate-js.yml and validate-cpp.yml
- [ ] Add Python setup step (similar to .github/actions/setup-js) to install dependencies and run python bindings tests
- [ ] Test against multiple Python versions (3.8, 3.9, 3.10, 3.11) using matrix strategy
- [ ] Integrate enums.py code generation into the validation pipeline
Add comprehensive benchmark regression tests to CI
The repo has benchmark infrastructure (benchmark/ directory with Benchmark.cpp, CMakeLists.txt, and test captures), but no automated CI workflow to detect performance regressions. This is critical for a layout engine where performance is a core value proposition. Adding benchmark regression detection would prevent performance degradation.
- [ ] Create .github/workflows/validate-benchmarks.yml that runs benchmark/Benchmark.cpp on Release builds
- [ ] Parse benchmark results and compare against baseline metrics stored in the repo
- [ ] Add benchmark result upload as artifact and comment on PRs with performance delta
- [ ] Document baseline generation process in CONTRIBUTING.md
Add fuzz test execution to CI/CD pipeline
The repo contains fuzz testing infrastructure (fuzz/ directory with FuzzLayout.cpp and CMakeLists.txt), but there's no visible CI workflow executing these fuzz tests. This leaves potential stability and security issues undetected. Integrating fuzz tests into the validation pipeline would improve robustness.
- [ ] Create .github/workflows/validate-fuzz.yml to build and run fuzz tests from fuzz/ directory
- [ ] Configure libFuzzer or AFL with reasonable corpus size and timeout limits for CI constraints
- [ ] Set up artifact capture for any fuzz crashes or coverage reports
- [ ] Reference fuzz testing instructions in CONTRIBUTING.md (currently missing)
🌿Good first issues
- Add Kotlin-specific unit tests in android/ mirroring the C++ test coverage (yoga/generic/tests/); currently only Java bindings are heavily tested, Kotlin API lacks parity verification
- Document the gentest HTML fixture syntax and auto-generation pipeline in a new gentest/README.md; currently requires reading yarn scripts and inline comments—a spec would help contributors add new layout test cases
- Implement performance regression benchmarks in CI/CD (.github/workflows/); benchmark/Benchmark.cpp exists but no automated threshold checks; add GitHub Actions step to run benchmark/benchmark on PR commits and compare against baseline
⭐Top contributors
Click to expand
Top contributors
- @mateoguzmana — 18 commits
- @NickGerleman — 17 commits
- @joevilches — 10 commits
- @J8118 — 6 commits
- @cortinico — 6 commits
📝Recent commits
Click to expand
Recent commits
966107f— Fix node ownership whendisplay: contentsis used (#1924) (j-piasecki)cd0c6fd— Remove commented-out duplicate code in YGMeasureTest (#1927) (J8118)0ea34b7— Fix import casing mismatch for gentest types.ts (#1929) (J8118)d382d33— xplat/js/react-native-github/packages/react-native/ReactCommon/yoga/yoga/YGConfig.cpp (generatedunixname1563563004708334)3072995— Fix Yoga Style equality crash for size-typed dimensions (#1931) (sbuggay)02d8ec6— Expose HadOverflow property in JavaScript bindings (#1930) (J8118)21680f2— Fix incorrect code examples in documentation (#1926) (J8118)9cc48ef— Fix typos in doc comment and benchmark runner (#1925) (J8118)fb8e618— Fix "instrinsic" typo in function name to "intrinsic" (#1928) (J8118)3acb6cc— Optimize style value resolution with handle-based approach (#1922) (paradowstack)
🔒Security observations
The Yoga project's build configuration (build.gradle) presents moderate security concerns primarily around credential handling and dependency management. The
- High · Hardcoded Gradle Plugin Versions —
build.gradle (plugins section). The build.gradle file specifies exact versions of Gradle plugins (Android 8.12.0, Kotlin 2.1.20) without version pinning or checksum verification. While not directly a secret, this approach can lead to supply chain attacks if plugin repositories are compromised. Consider using version catalogs and dependency verification. Fix: Implement Gradle dependency verification by enabling checksum validation. Use version catalogs (libs.versions.toml) for centralized dependency management and enable lock files for reproducible builds. - High · Insecure Credentials Handling in Gradle Build —
build.gradle (lines 29-30, 34-35). Sonatype credentials (SONATYPE_USERNAME and SONATYPE_PASSWORD) are retrieved using findProperty() from Gradle properties without validation or encryption. If credentials are stored in gradle.properties or environment variables without proper protection, they could be exposed in build logs or version control. Fix: Never store credentials in gradle.properties or version control. Use Gradle's encrypted properties, environment variables with restricted access, or a secrets management system. Implement credential masking in CI/CD pipelines. Consider using OAuth tokens or service accounts instead of username/password. - High · Unencrypted Nexus Repository Connection —
build.gradle (lines 35-36). The Sonatype Nexus repository is configured with HTTP-based staging API URL (ossrh-staging-api.central.sonatype.com) without enforced HTTPS. This could expose credentials and artifacts during transmission. Fix: Ensure all repository URLs use HTTPS with certificate pinning where possible. Verify the nexusUrl and snapshotRepositoryUrl use secure protocols. Consider using certificate pinning for production Maven repositories. - Medium · Missing Dependency Version Constraints —
build.gradle (plugins section). Gradle plugins are applied with 'apply false' but no explicit version constraints are documented for transitive dependencies. This could lead to unexpected dependency resolution and potential inclusion of vulnerable transitive dependencies. Fix: Implement a comprehensive dependency management strategy using the dependencyManagement block or Gradle's platform/bom approach. Regularly scan dependencies using tools like OWASP Dependency-Check or Snyk. Lock dependency versions with gradle.lockfile. - Medium · No SNAPSHOT Version Security Control —
build.gradle (lines 22-26). The build.gradle file automatically appends '-SNAPSHOT' to versions when USE_SNAPSHOT property is set, but there's no validation that SNAPSHOT artifacts are not accidentally published to release repositories. Fix: Add explicit checks to prevent SNAPSHOT versions from being published to release repositories. Implement CI/CD pipeline guards that validate version numbering before publication. Use Maven's release-plugin or equivalent safeguards. - Medium · Unclear Nexus Repository Configuration —
build.gradle (lines 32-39). The nexusPublishing configuration uses a staging URL and snapshot repository URL without clear documentation of the approval/promotion workflow. This could lead to accidental publishing or misconfiguration. Fix: Document the complete release process including staging, verification, and promotion steps. Add automated checks to ensure only release builds are promoted. Consider implementing a manual approval gate in the CI/CD pipeline. - Low · Missing Repository Security Configuration —
build.gradle (lines 16-19). The allprojects repositories configuration uses default Google and Maven Central repositories without additional security hardening such as repository authentication or integrity checking. Fix: Consider using private mirrors for internal dependencies. Enable repository authentication for private repositories. Implement package integrity verification and consider using a Software Composition Analysis (SCA) tool for dependency security monitoring. - Low · No Input Validation on Build Properties —
build.gradle (lines 22-26). The VERSION_NAME property is used without validation to construct the version string. While the risk is low for this specific use case, it's a general anti-pattern. Fix: Add validation to ensure VERSION_NAME follows semantic versioning standards. Use Gradle's built-in validation mechanisms or custom validation tasks to enforce version format.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.