Parley: the Linebender text stack
Text layout for Xilem and friends.
Parley is the Linebender project's rich-text layout engine, the sibling of cosmic-text. You build a layout from a string, attach styles to ranges, break it into lines at a width, and get back runs of glyphs ready for a renderer. The builder borrows a FontContext and a LayoutContext, which you keep around so they can cache work between frames.
use parley::{FontContext, LayoutContext, StyleProperty};
fn main() {
let text = "Hello, parley. This paragraph wraps onto several lines.";
let mut font_cx = FontContext::new();
let mut layout_cx: LayoutContext<()> = LayoutContext::new();
let mut builder = layout_cx.ranged_builder(&mut font_cx, text, 1.0, true);
builder.push_default(StyleProperty::FontSize(16.0));
let mut layout = builder.build(text);
layout.break_all_lines(Some(180.0));
println!("{} lines, {:.0} x {:.0}", layout.len(), layout.width(), layout.height());
} 3 lines, 156 x 48Styling applies to byte ranges, keeping text and style separate. A finished layout is organised as lines, then runs of same-font glyphs. Those are precisely what Vello-family renderers (and any other) draw.
use parley::{FontContext, FontWeight, LayoutContext, StyleProperty};
fn main() {
let text = "Bold start, then regular text.";
let mut font_cx = FontContext::new();
let mut layout_cx: LayoutContext<()> = LayoutContext::new();
let mut builder = layout_cx.ranged_builder(&mut font_cx, text, 1.0, true);
builder.push_default(StyleProperty::FontSize(18.0));
// Style a byte range; the builder keeps spans separate from the text.
builder.push(StyleProperty::FontWeight(FontWeight::BOLD), 0..10);
let mut layout = builder.build(text);
layout.break_all_lines(None);
// Each line is a sequence of runs of same-font glyphs, ready for a renderer.
for line in layout.lines() {
println!("line with {} items", line.items().count());
}
} line with 2 itemsParley depends on fontique (font selection), harfrust (shaping), skrifa, and accesskit (so text layouts can describe themselves to screen readers). It is the text engine for Xilem and for Blitz/Dioxus Native (both on 0.6.0 in our lockfiles), and Slint's lockfile resolves Parley 0.11.1. Linebender's Q1 2026 report also lists Bevy among its adopters.