DOM-free layout engine combining Yoga (flexbox) with Pretext (text measurement).
bun install— install dependenciesbun run check— type-check with tscbun test— run testsbun run build— emit ESM todist/
src/index.ts— public API entry point (re-exports from engine and types)src/engine.ts— core engine: Yoga tree building, Pretext MeasureFunction wiring, layout computationsrc/types.ts— declarative input types (BoxNode, TextNode, FlexProps) and computed output typessrc/index.test.ts— tests (box layout tests run in Bun; text tests require browser canvas)tsconfig.build.json— publish-time emit config fordist/.github/workflows/release.yml— GitHub Actions workflow: publishes to npm on GitHub Release
A GitHub Actions workflow handles npm publishing for both packages. To release:
- Create a GitHub release with a
v-prefixed tag (e.g.gh release create v0.2.0 --title "v0.2.0" --notes "...") - The workflow automatically:
- Builds and publishes
texturato npm - Then builds and publishes
@razroo/textura-mcpto npm (with matching version and dependency)
- Builds and publishes
- Requires
NPM_TOKENsecret configured in the repo
Do not publish manually via npm publish — use the release workflow.
init()loads Yoga WASM viayoga-layout/load(async). Must be called beforecomputeLayout.computeLayout()builds a Yoga node tree, setsMeasureFunctionon text leaves using Pretext'sprepare()+layout(), runscalculateLayout(), reads back geometry, and frees the tree.- Text nodes are Yoga leaf nodes (no children). The MeasureFunction calls Pretext to get height given Yoga's width constraint.
- Yoga config uses
setUseWebDefaults(true)to match CSS browser flex defaults. - Yoga nodes must be manually freed (
freeRecursive). This happens insidecomputeLayoutafter readback. - Text measurement requires a canvas context (browser
document.createElement('canvas')orOffscreenCanvas). Tests that need text measurement are skipped in Bun. - Keep
.jsspecifiers in imports for plain tsc emit compatibility.