@fr0/layout-engine
v0.1.0
Published
CSS Flexbox + Grid layout engine for fr0. Thin wrapper over taffy-layout (WASM Taffy bindings).
Readme
@fr0/layout-engine
CSS Flexbox + Grid layout engine for fr0.
Status
Spike (2026-04-10). This package is being evaluated against taffy-layout
(third-party WASM bindings for DioxusLabs/taffy) as the backend. The goal is to
replace the hand-rolled core/apply-layout.ts with a spec-compliant engine so
templates can use fit-content, flexGrow, Grid, and other flexbox features
that the hand-rolled implementation would take months to reproduce.
Why not hand-roll it ourselves?
See docs/layout-engine-decision.md. Short version: Figma, React Native, Bevy, and Zed all hit this wall and none of them hand-rolled a layout engine past the toy stage. We're not going to be the exception.
Why taffy-layout and not Yoga?
- CSS Grid support. Yoga is Flexbox-only; Taffy (via
taffy-layout) has Grid. AI-generated SaaS templates are going to want Grid. - Active maintenance. Taffy upstream is actively developed; Yoga is in maintenance mode at Facebook.
- Rust + wasm-bindgen toolchain lines up with the TS monorepo better than Yoga's Emscripten build.
Trade-off: taffy-layout is third-party, not official
taffy-layout is published by ByteLandTechnology, not DioxusLabs. The
official Dioxus WASM bindings are in-progress as PR #927 on DioxusLabs/taffy
but not merged yet. When that PR merges and ships as the official taffy-wasm
package, this package's backend swap target is to migrate.
The public API of @fr0/layout-engine is designed to be
backend-agnostic so the swap is bounded: change one adapter file, re-run the
determinism regression suite, ship.
API
import { computeLayout } from '@fr0/layout-engine';
const result = await computeLayout(
{
// root: CSS-style flex/grid container + children tree
display: 'flex',
flexDirection: 'row',
width: 400,
height: 200,
gap: 10,
padding: 8,
children: [
{ width: 100, height: 50 },
{ flexGrow: 1, height: 50 },
],
},
{ width: 400, height: 200 }, // available space
);
// result: { x, y, width, height, children: [...] }Determinism
Layout output must be byte-identical across (a) repeated calls with the same
input on the same machine and (b) the same input on different machines. The
__tests__/determinism.test.ts suite enforces (a); (b) is verified by the
fr0 determinism test suite (@fr0/testing) against committed
golden files.
