# Parley computes glyph positions, then leaves the pixels to you

> Parley is a Rust library for rich text layout: it turns a string plus a font choice into positioned glyph runs, delegating font enumeration, shaping and Unicode analysis to four supporting crates. It ships no renderer, so drawing remains your problem.

**linebender/parley** — Rich text layout library

- Repository: https://github.com/linebender/parley
- Stars: 768 · Forks: 138
- Language: Rust
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/linebender-parley

## Parley hands back coordinates, not a picture

Parley provides an API for implementing rich text layout. The definition the README gives is precise: text layout means computing x/y coordinates for each glyph in a string of text. On top of those coordinates, Parley determines a glyph's size, performs line breaking, and resolves bidi direction, and it ships utilities for text selection and editing.

That boundary matters. Parley is not a widget toolkit and it is not a renderer. The repository keeps drawing out of the core crate and puts it in examples instead: examples/swash_render, examples/tiny_skia_render and examples/vello_cpu_render each pair the layout output with a different painting backend, and examples/editor covers the editing utilities. The workspace also holds parley_engine, parley_data and parley_data_gen alongside the main parley crate.

So the intended user is an engineer writing a Rust program that has to place text precisely: a text editor, a document viewer, a canvas-based UI, or a terminal-independent toolkit. If your program already draws through a browser engine or a full widget stack, Parley is the wrong altitude, because you would be reimplementing layout that another layer already owns.

## The text stack is split across four crates with distinct jobs

Parley does not implement text processing from scratch. It sits on four key dependencies, and the README describes each as covering a different piece of the text-rendering process.

Fontique handles fonts: enumeration and fallback. HarfRust handles shaping, mapping runs of Unicode codepoints to glyphs. Skrifa handles reading TrueType and OpenType font files and exposing higher level metrics. ICU4X handles text analysis and internationalisation, which for Parley covers locale and language recognition, bidirectional text evaluation, text segmentation, emoji recognition and NFC/NFD normalisation.

Parley itself keeps the layout algorithm and the selection and editing utilities. The workspace manifest treats Fontique and the other pieces as local path dependencies rather than registry lookups, so the crates you pull are the ones sitting next to the source in this repository. Fontique and Parley are versioned together at 0.12.0 in the workspace manifest, and the emoji support lives in its own crate, parley_emoji, with its own license terms.

The practical consequence is that an adopter inherits four upstream projects, each with its own release cadence, and a compatibility surface that is wider than the single parley crate suggests.

## Fontique enumerates system fonts and chooses the fallback for you

Two distinct jobs sit inside Fontique, and they behave differently.

Font enumeration means listing all the fonts installed on the system, then collecting metadata about them: whether they are serif, sans-serif or monospace, their weight, the code points they cover. The library is also responsible for loading fonts into memory, and it does so with memory-mapped IO so that only portions are pulled in lazily and can be shared between processes on the system.

Font fallback is the other job, and it is the one that shapes real output. Fonts typically do not cover the entire Unicode range, so you end up with separate fonts for latin text, chinese text, arabic text and usually another for emoji. When arabic text or an emoji appears inside latin text, the caller does not normally specify a font for it. Font fallback is the process that makes that choice.

This is the piece that decides whether mixed-script text renders correctly in your application without you building a script-to-font table yourself. It is also the piece most sensitive to the fonts actually installed on the machine running your program.

## HarfRust shapes, Skrifa turns glyph outlines into drawable paths

HarfRust is described as a Rust port of the HarfBuzz text shaping engine. Shaping means mapping runs of Unicode codepoints to specific glyphs within fonts. That covers ligatures and emoji modifiers, plus considerably more complex transformations for some scripts.

Skrifa sits on the font file side. It reads TrueType and OpenType fonts and is built on top of the read-fonts low-level parsing library, which is part of the oxidize project. Where read-fonts gives raw representations, Skrifa provides higher level metrics and, notably, converts the raw glyph representations in font files into scaled, hinted vector paths suitable for rasterisation.

Taken together, these two crates explain where Parley's output boundary sits. Shaping decides which glyph each character becomes; Skrifa gives you the geometry of those glyphs. Neither one paints them. The examples folder shows the two obvious ways to finish the job, one through a rasteriser and one through a vector renderer, and the presence of three separate render examples indicates that choosing a backend is a decision the user makes rather than one Parley settles.

## ICU4X and Parley split the Unicode work in two places

Unicode analysis is not entirely delegated. ICU4X supplies the character knowledge, while Parley applies part of it.

On the ICU4X side, the README lists locale and language recognition, bidirectional text evaluation, text segmentation, emoji recognition, NFC/NFD normalisation, and other Unicode character information. On the Parley side, the layout work explicitly includes determining a glyph's size, line breaking, and bidi resolution.

Bidi therefore crosses the boundary: ICU4X evaluates the bidirectional situation, and Parley resolves it into concrete ordering and coordinates. That split is worth understanding before you try to debug an RTL layout problem, because the question of which layer failed is not obvious from the crate name.

Text segmentation and normalisation are more plainly ICU4X work, and Parley consumes them rather than reimplementing them. The net effect for an adopter is that script detection, segment boundaries and emoji recognition arrive already solved, which is the part of text layout most projects get wrong on their own.

## Installing Parley means picking a Rust version first

Parley is published to crates.io as parley, and the documentation is built on docs.rs. The README does not give a step-by-step installation, so the practical starting point is the crate registry entry and the docs site, with the workspace manifest showing which version the source tree is currently on.

The constraint to check before anything else is the minimum supported Rust version. The README states that this version of Parley has been verified to compile with Rust 1.88 and later. The workspace manifest records the same number, and it also pins the edition and the license identifier used across every crate in the workspace.

```toml
[workspace.package]
version = "0.12.0"
edition = "2024"
rust-version = "1.88"
license = "Apache-2.0 OR MIT"
repository = "https://github.com/linebender/parley"
```

Future versions might raise the Rust requirement, and the README warns that this is not treated as a breaking change, so it can happen even in a small patch release. That makes your toolchain pin a moving part in practice, and the manifest itself notes that the MSRV value must be kept in sync with RUST_MIN_VER in .github/workflows/ci.yml.

If a build fails because one of the dependencies has already moved to a higher Rust requirement and you do not want to upgrade your toolchain, the README offers a downgrade path. Replace the placeholder with the name and version of the dependency that caused the failure.

```bash
# Use the problematic dependency's name and version
cargo update -p package_name --precise 0.1.1
```

After that, the first real use is a layout call over a string with a chosen font, which means wiring font enumeration and fallback through Fontique before any glyph appears. The examples/editor directory is the closest thing in the tree to a first use that exercises selection and editing rather than painting alone.

## The Web Platform Tests are the correctness bar, not a browser dependency

Parley does not define correctness on its own terms. The README points to the Web Platform Tests, which contain a large number of tests for correct text layout, and explains that these can be run against Parley using Blitz, the WPT test runner from the Dioxus Labs project. A Parley WPT guide is linked from the Blitz repository under docs/parley.md.

That is a different approach from treating a specification document as the source of truth. Rather than arguing about what the correct line break is, the project measures itself against the tests browsers are expected to pass, so Parley can be compared to the behaviour of an existing rendering engine instead of to a description of it.

This also sets Parley apart from a rule-based line breaker written in isolation: the reference behaviour is the one users already see in a browser, including the awkward cases around scripts, emoji and mixed directions. If your application is expected to match web output, running this suite is the way to know where it differs, and the runner lives outside this repository, which adds a separate tool to maintain.

## What the project leaves out, and where the licenses diverge

Two gaps are worth naming before an adoption decision. The README does not document rollback, so there is no documented procedure for reverting to an earlier Parley version in a deployed application. It also does not provide a renderer, so painting is entirely delegated to your chosen backend.

Licensing needs care as well, because the dual Apache-2.0 OR MIT grant at the workspace level does not cover everything. The README states that parley_emoji is licensed only under its MIT license, with an attribution that differs from Parley's own MIT license, and points to ./parley_emoji/README.md. It states that parley_tests/tests/emoji is licensed only under the Apache License, Version 2.0 and not the MIT license, with details under ./parley_tests/tests/emoji/README.md. Some other files used for tests and benchmarks carry different licenses, detailed in ./parley_dev/README.md. This is a licensing fact rather than legal advice, but it means the crate you depend on and the emoji support you rely on may not be covered by the same terms.

On maintenance, the repository is not archived and the last push was on 2026-10-19. Recent releases include v0.12.0 on 2026-10-09, Parlance v0.1.1 on 2026-10-09, and v0.11.1 on 2026-08-16. The line is still pre-1.0, and the README states plainly that the Rust version requirement may increase in a patch release, so treat the dependency set as something you re-check when you upgrade.

## Conclusion

Parley suits Rust teams that need to control text layout directly, including selection and editing utilities, and that can accept a pre-1.0 crate line and a dependency stack of their own. It is a poor fit if you want a finished text renderer, if you need a Windows, macOS or Linux install path documented beyond the crate registry, or if you need emoji support under the Apache license alone. Before adopting, check the MSRV line against your toolchain, read the per-crate license notes under ./parley_emoji/README.md and ./parley_tests/tests/emoji/README.md, and confirm that the missing pieces in this repository, such as rollback instructions, are not supplied by your own tooling.

## FAQ

### What is Parley used for in Rust?

Parley provides an API for implementing rich text layout, meaning it computes x/y coordinates for each glyph in a string of text and adds glyph sizing, line breaking and bidi resolution, plus utilities for text selection and editing. It performs layout only and leaves painting to a separate backend.

### What Rust version does Parley require?

The README states that this version of Parley has been verified to compile with Rust 1.88 and later. The version could rise in a future release, and the README says such an increase is not treated as a breaking change, so it can arrive in a patch release.

### Does Parley include a renderer, and how is text correctness checked?

Parley ships no renderer; the repository places backends in examples such as swash_render, tiny_skia_render and vello_cpu_render. Correctness is checked against the Web Platform Tests, run with the Blitz WPT test runner from the Dioxus Labs project.

### Which crates does Parley depend on?

The README names four key dependencies covering different parts of the text-rendering process: Fontique for font enumeration and fallback, HarfRust as a Rust port of the HarfBuzz shaping engine, Skrifa for reading TrueType and OpenType fonts, and ICU4X for text analysis and internationalisation.

## Sources

- [Issues](https://github.com/linebender/parley/issues)
- [License: Apache-2.0](https://github.com/linebender/parley/blob/main/LICENSE)
- [linebender/parley on GitHub](https://github.com/linebender/parley)
- [README](https://github.com/linebender/parley/blob/main/README.md)
- [Releases](https://github.com/linebender/parley/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/linebender-parley
