A string of Unicode code points is not yet readable text. Before pixels appear, software must choose glyphs from a font, combine and reorder them where a writing system requires it, and calculate each glyph's advance and offset. Applications that treat this as a character-to-picture lookup soon meet ligatures, contextual forms, combining marks, variation axes, emoji, and scripts whose visible order does not mirror storage order.
HarfBuzz performs that middle transformation for browsers, operating systems, toolkits, design applications, and game engines. Its public shaping entry point is compact enough to look routine; the rules and compatibility expectations behind it span fonts and writing systems. That contrast is the organizing idea in Behdad Esfahbod's 2026 talk HarfBuzz at 20!, recorded at the Web Engines Hackfest in A Coruña.[1][2][3]
The talk is also an unusually clear open-source maintenance study. Esfahbod connects a stable C interface to thousands of output tests, a Rust port, browser-scale performance work, and experimental font programmability. His personal account traces the project back to a long-running effort to make Persian work well in open-source systems, while an earlier independent history explains how that immediate problem grew into shared infrastructure.[7][8] Watch the talk for the demos; use the annotations below to inspect the contracts they depend on.
Image context: the lead image is an archival reproduction of a sixteenth-century Persian Nastaliq folio. It is a material reference for contextual joining and mark placement, not an example of HarfBuzz output.[9]
At 0:46, a small API names a large transformation
Esfahbod describes HarfBuzz as a font platform with a C library interface, command-line tools, and several components around the core shaper.[1] The shaper's basic contract can be stated precisely. A caller supplies an hb_font_t, a buffer containing Unicode code points, and optional typographic features. The buffer also carries direction, script, and language properties. After hb_shape() returns, that same buffer contains glyph identifiers in visual order plus positioning information: horizontal and vertical advances and x/y offsets.[3]
That mutation is more than an implementation detail. The buffer changes meaning across the call, from encoded text to a font-specific display plan. The client remains responsible for choosing and loading a font, segmenting runs with coherent properties, arranging lines and paragraphs, and drawing the returned glyphs. HarfBuzz deliberately stops short of being a complete text-layout engine.[3][5] A useful integration diagram is therefore a boundary, not a blob:
Unicode text → itemize and choose font → shape one run → position lines → draw glyphs
Most application developers should reach that pipeline through a platform or UI toolkit. A team that calls HarfBuzz directly inherits the seams: font fallback, bidirectional paragraph processing, run segmentation, line breaking, and the relationship between source text and the glyph stream. A successful “hello” in Latin exercises almost none of those seams. The minimum serious fixture set includes combining marks, a right-to-left script, ligatures, mixed directions, variation settings, missing glyphs, and a line break near a shaped sequence.
At about 2:17, Esfahbod emphasizes that the C API and ABI have remained stable across the project's long life.[1] The repository makes the narrower guarantee explicit for the public headers while allowing source and internal structures to evolve.[5] This is the first maintenance lesson: keep the caller's vocabulary small, then spend the complexity budget behind it. Stability at the symbol boundary, however, is only half the promise. A shaper can preserve every function signature and still move a mark, choose a different ligature, or return clusters that break selection.
At 5:23, compatibility becomes an empirical standard
The talk's history of interoperability begins with matching platform shapers. When Microsoft, Apple, and open implementations differed, the project compared results and diverged only with a reason. By 6:25, Esfahbod says the suite contains more than 6,000 shaping tests and that browsers and independent researchers continuously fuzz the engine.[1] LWN's earlier account supplies the social context: competing implementations once produced divergent results, and broad desktop adoption made HarfBuzz a shared place to resolve script and font behavior.[7]
This creates a feedback loop that a version number cannot describe. Browser deployment exposes rare combinations of font tables, scripts, and malformed inputs. Reports become reduced test cases. Font makers test against the implementation their readers actually use. Those fonts then enlarge the effective compatibility surface. HarfBuzz is still an implementation of published formats and shaping models, but deployed behavior also becomes evidence that downstream software expects a particular answer.[1][5]
The engineering consequence is practical. A replacement needs more than equivalent feature names. It needs differential tests over actual inputs and outputs: glyph IDs, order, positions, clusters, flags, errors, and performance. Tests should preserve the font and text that triggered each defect, because a simplified ASCII surrogate usually deletes the relevant condition. Fuzzing covers a different axis: parsers and shapers consume untrusted binary fonts, so “no crash or memory error” is a necessary property even when the input has no valid visual interpretation.
Adoption also makes optimization asymmetric. At 8:29, Esfahbod describes multi-fold improvements on some shaping workloads, work partly driven by Chromium benchmarks.[1] Speed matters at browser scale, yet an optimization that silently degrades a less frequently benchmarked script spends somebody else's correctness. His answer during the closing questions is telling: benchmark Arabic, Devanagari, and other required work too. Performance suites encode product priorities; a representative suite prevents the common path from becoming the only protected path.
Clusters preserve the route back to the text
Glyph shaping is not one input character becoming one output glyph. Several code points may form one ligature; one character may produce multiple glyphs; marks can move; glyphs may reorder. HarfBuzz carries a cluster value on each input code point and propagates those values through splitting, merging, and reordering. The cluster documentation carefully distinguishes this bookkeeping unit from a Unicode grapheme cluster: it is a mapping between the character stream and the glyph stream, with behavior controlled by the buffer's cluster level.[4]
That mapping is what keeps editing attached to what a reader sees. A layout client uses it to place a caret, expand a selection, transfer color or other character attributes, extract text from a PDF, and decide where a line may safely break. HarfBuzz can mark glyph positions as unsafe break points when shaping a segment in isolation might produce a different result.[3][4] If an integration discards cluster values after drawing, the page can look correct while its cursor, search highlights, copy-and-paste, or line wrapping remain wrong.
Clusters therefore deserve first-class tests. Shape a run, break it at every candidate boundary, reshape the pieces, and compare the combined result where a break is meant to be safe. Walk cursor positions in both logical directions. Select text that participates in a ligature and text with multiple combining marks. Confirm that the interface's chosen cluster level matches its editing model. These are user-visible invariants, even though the bug sits below the widget layer.
The distinction also clarifies ownership. HarfBuzz reports the information needed to reason about a shaped run; it does not dictate a product's cursor policy. A code editor, a terminal, and a publishing system may choose different movement and selection behavior. Their implementations can differ while all respecting the same mapping rather than reconstructing it from glyph geometry.
From 9:29, HarfRust inherits an oracle
The Rust section could have been presented as a language migration. Instead, it reads as a study in preserving semantics. Esfahbod surveys several attempts at safe Rust shaping, then explains how HarfRust grew from a fork of RustyBuzz inside a broader Rust font-toolchain effort. At 12:30 he reports closing much of an earlier performance gap and measures remaining discrepancies against the existing corpus. At 13:33, a Servo experiment runs the C++ and Rust shapers side by side and reports differences.[1]
That side-by-side arrangement is the important architecture. The mature implementation becomes an oracle while the port is still earning trust. Given the same font bytes, buffer properties, features, and text, both backends should emit comparable glyph sequences, positions, clusters, and flags. A mismatch is then a small, reproducible investigation rather than a screenshot complaint. The method scales beyond typography: semantic migrations of parsers, databases, compilers, or protocol stacks become safer when old and new implementations can shadow the same production-shaped inputs.
The current HarfRust repository states its boundary plainly. It aims to match the HarfBuzz shaper and Unicode functionality, and reports passing most upstream tests and fuzzing, but it is not the entire C++ project in Rust. System integrations, Graphite shaping, an Arabic fallback shaper, and some other components are absent; font parsing is delegated to the read-fonts ecosystem. The README also publishes known differences and performance expectations rather than flattening them into a “compatible” badge.[6]
That transparency changes rollout planning. A team should inventory which HarfBuzz surface it actually uses before announcing a replacement. Then it can shadow representative traffic, compare outputs, set explicit exception budgets, benchmark by script and font, and preserve a fallback while unexplained differences remain. Memory safety is a valuable property of the new implementation. It does not waive visual compatibility, error behavior, or latency.
The port also answers a project-health concern raised near 2:47, where Esfahbod describes a low bus factor around a small group of maintainers.[1] A second implementation does not automatically create maintainers, and parallel codebases can increase review load. It can, however, turn previously implicit behavior into portable fixtures, involve another language ecosystem, and expose which modules were coupled to one parser or platform. The migration's durable artifact may be the compatibility harness as much as the port itself.
At 16:37, programmable fonts move the trust boundary
The talk's most speculative section proposes putting sandboxed WebAssembly in a font so the font can carry shaping logic that fixed tables express poorly.[1] The demos make the motivation concrete: intricate Arabic mark placement, recursively composed Egyptian hieroglyphs, and the optical positioning of Ruq'ah calligraphy strain a model in which a general shaper interprets static tables. Moving specialized logic with the font could let a type designer encode behavior without waiting years for a new table format and interoperable engine support.
This is a research direction, not a deployment recommendation. It changes a font from untrusted structured data into untrusted data plus executable behavior. Any production design would need tight limits on memory and instructions, deterministic outputs, stable host calls, cache rules, version negotiation, denial-of-service defenses, and an accessibility story for the mapping back to characters. Sandboxing reduces some risk; it does not decide how much work a page may demand or how results remain reproducible across engines.
The proposal nevertheless illuminates the whole talk. HarfBuzz succeeded partly because it concentrated evolving script and font knowledge behind a stable boundary. HarfRust tests whether that knowledge can move between implementations without changing answers. Programmable fonts ask whether some of it can move again, from the shared engine into a font-specific sandbox. Each move changes who can innovate, who must standardize, and where compatibility tests must run.
For an engineering team, the immediate takeaway is modest. Treat shaping as a semantic subsystem rather than a rendering helper. Keep its input properties explicit. Preserve clusters and safety flags through layout. Test outputs with real scripts and fonts, including malformed inputs. Measure complex scripts in performance work. And when replacing mature infrastructure, build the differential oracle before scheduling the cutover. HarfBuzz's smallest function call is valuable because twenty years of accumulated evidence stand behind its result.
Sources
- Web Engines Hackfest, “HarfBuzz at 20!” by Behdad Esfahbod (2026) — embedded conference talk.
- Igalia, “Web Engines Hackfest 2026” — official event recap, program context, and talk provenance.
- HarfBuzz Manual, “Getting started with HarfBuzz” — official shaping pipeline, buffer properties, glyph output, positions, and flags.
- HarfBuzz Manual, “Clusters” — official account of character-to-glyph mapping, cluster levels, reordering, and editing uses.
- HarfBuzz repository — official project scope, public API stability, components, users, testing, and security guidance.
- HarfRust repository — official compatibility status, architecture, performance notes, known differences, and omitted integrations.
- LWN, “HarfBuzz brings professional typography to the desktop” (2017) — independent project history and adoption context.
- Behdad Esfahbod, personal project history and 2026 talk index — author provenance and the Persian-text motivation behind HarfBuzz.
- Smithsonian Institution, “Page of calligraphy by Muhammad Husayn al-Tabrizi,” Wikimedia Commons — source and rights page for the lead image.