taffy

A flexible, high-performance Rust layout engine implementing CSS Flexbox, Grid, and Block algorithms.

Library
Cargo
v0.14.0
3,545stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
89/100Excellent
Development Activity96
Maintenance100
Community64
Maturity56
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
88/100Excellent
Architecture88
Code Quality90
Innovation85
Learning Curve90

Taffy is a Rust layout engine implementing the CSS Block, Flexbox, and Grid algorithms as a standalone, embeddable library. Rather than shipping a full UI framework, it exposes layout computation as a reusable building block: a high-level TaffyTree API for standalone use, and a low-level trait API for embedding Taffy’s algorithms behind an existing tree or widget representation.

It’s the layout engine behind a wide range of unrelated Rust UI projects — the Servo and Blitz web engines, the Bevy game engine, the Zed and Lapce text editors (via GPUI and Floem), the Slint GUI toolkit, and the iocraft terminal UI library — because each would otherwise have needed to hand-roll Flexbox and Grid from scratch.

What You Get

  • Two APIs — a high-level TaffyTree for standalone use and a low-level trait API for embedding Taffy’s algorithms behind an existing tree/widget representation
  • CSS-faithful Flexbox, Grid, and Block layout algorithms, so existing CSS knowledge transfers directly to Rust
  • Built-in per-node layout caching (tree/cache.rs) that invalidates on style change, keeping repeated layout passes fast
  • no_std compatibility with opt-in std/alloc features, for embedded and constrained targets
  • Measure-function support (compute_layout_with_measure) for integrating text, image, or other externally-sized content into the layout tree
  • Optional serde feature for (de)serializing Style structs

Common Use Cases

  • Laying out game engine UI and HUDs (Bevy)
  • Laying out terminal UI widgets (iocraft)
  • Backing the layout engine of a custom UI framework or renderer (Dioxus’s Blitz, Slint, Zed’s GPUI, Lapce’s Floem)
  • Laying out an alternative web engine’s rendering tree (Servo)
  • Integrating text or image measurement into a layout tree via measure functions

Under The Hood

Architecture Taffy is organized around a trait-based low-level API (tree/traits.rs: TraversePartialTree, LayoutPartialTree, TraverseTree, RoundTree, PrintTree) that lets a consumer plug in its own tree storage, plus a high-level TaffyTree (src/tree/taffy_tree.rs) built on slotmap for node storage with built-in style/layout/cache management. compute/mod.rs dispatches into per-algorithm modules (block.rs, flexbox.rs, grid/, float.rs, leaf.rs) that expose compute_block_layout, compute_flexbox_layout, compute_grid_layout, compute_root_layout, compute_cached_layout, and compute_hidden_layout — each written against the LayoutPartialTree trait rather than the concrete tree, so the algorithms are fully decoupled from storage and TaffyTree is just one implementation of that interface. Caching lives in tree/cache.rs, keyed per node. #![deny(unsafe_code)] plus no_std compatibility (with alloc/std opt-in features) show the architecture is deliberately built to run in embedded and game-engine contexts, not just conventional Rust apps. Because the LayoutPartialTree trait is the extension point every downstream consumer (Bevy, Servo, Zed’s GPUI, Dioxus’s Blitz) implements, changes to that trait ripple through all of them.

Tech Stack A Rust crate (edition 2021, MSRV 1.71) with a minimal required dependency footprint — arrayvec for stack-allocated vectors — and everything else feature-gated: slotmap (taffy_tree feature, node storage), smallvec (grid feature), serde (serde feature, style struct serialization), and cssparser (parse feature, FromStr support for style types). It’s #![no_std] by default with std/alloc opt-in, so it compiles for embedded and wasm targets. Dev-dependencies (serde_json, roxmltree, a local taffy_test_helpers crate) support a cargo workspace of test tooling under scripts/ (gentest, getchrome, format-fixtures, import-yoga-tests) used to generate and import layout test fixtures from a real browser and from Meta’s Yoga library, which is also used as the comparison baseline in criterion benchmarks (benches/dummy_benchmark.rs). It ships purely via crates.io/docs.rs with no runtime services.

Code Quality The tests/ directory (21 files, including hand_written.rs and xml.rs) loads a large set of fixture cases generated against real browser layout output via scripts/import-yoga-tests and scripts/getchrome, so correctness is checked against actual CSS engine behavior rather than hand-asserted expectations alone. #![deny(unsafe_code)], #![warn(missing_docs)], and #![warn(clippy::missing_docs_in_private_items)] are set at the crate root, so undocumented items and unsafe code fail CI rather than relying on convention. CI (.github/workflows/ci.yml) runs the standard test/clippy/fmt gate, and a separate dependencies.yml workflow paired with deny.toml audits dependency licenses and security advisories via cargo-deny. Naming maps directly onto CSS spec terminology (FlexDirection, AlignItems, GridTemplateColumns), which keeps the API legible to anyone who already knows CSS.

API Design Taffy offers both a batteries-included high-level API (three calls — new_leaf/new_with_children/compute_layout — produce a full computed layout) and a low-level trait API for framework authors who don’t want to adopt Taffy’s own node storage. That dual-API generosity is unusual for a layout engine and is likely why it’s been embedded as the layout backend of half a dozen unrelated projects (Bevy, Servo, Zed’s GPUI, Dioxus’s Blitz, Slint, Floem) rather than each one forking or reimplementing layout independently. The crate ships extensive rustdoc plus runnable examples (basic, flexbox_gap, grid_holy_grail, measure, and three custom_tree_* variants demonstrating the low-level API) that double as the primary onboarding path. What friction exists comes from CSS Grid’s inherent complexity rather than an awkward Rust API — the crate mirrors upstream CSS semantics faithfully instead of inventing its own vocabulary.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search