ttf-parser reads TrueType fonts without allocating or panicking
A high-level, safe, zero-allocation TrueType font parser.
At a glance
- What is it?
- harfbuzz/ttf-parser is a Rust library, with a C API, for parsing TrueType, OpenType and AAT fonts using no heap allocation and no unsafe code. The README states the crate is in maintenance mode, with bug fixes only and new projects pointed at fontations instead.
- Who is it for?
- Use ttf-parser when you need to read untrusted font data in Rust or C under a hard memory and panic budget, for example inside a server that accepts uploaded fonts. Do not start a new project on it: the crate is in maintenance mode, the README says new table support and performance work are out of scope, and it points new users to fontations.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 78 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A parser for untrusted fonts that refuses to allocate
The problem ttf-parser addresses is narrow: reading font tables out of a file that you do not control, without the usual Rust failure modes getting in the way. The crate lists its guarantees as a short list. It has zero heap allocations, zero unsafe code and zero dependencies, it can run under no_std or WASM, and it forbids unsafe code outright. It parses TrueType, OpenType and AAT, and it can be used as a Rust library or through a C API. The panic policy is unusually strict for a parser: the library must not panic, and any panic is called out as a critical bug worth reporting. That combination, no allocation and no panic, is what makes the crate attractive for embedding in a service that accepts fonts from the network. Font data is exactly the kind of input where a malformed table triggers an enormous offset or a cyclic reference, so a parser that bounds its own work and refuses to abort the process is worth the constraint of writing without allocators.
The Cargo feature flags that decide what your binary pays for
The crate is heavily configurable through Cargo features, and the defaults are generous. The manifest declares the default set as std, alloc, opentype-layout, apple-layout, variable-fonts and glyph-names. Turning features off is how you cut binary size, and the manifest comments explain the price of each. Enabling variable-fonts almost doubles the binary size because it pulls in avar, CFF2, fvar, gvar, HVAR, MVAR and VVAR tables. Disabling glyph-names removes the built-in store of roughly 500 default TrueType glyph names, which exist because TrueType files do not ship them. Two flags control the standard library relationship: std enables alloc, and the no-std-float feature pulls in the optional core_maths dependency, which the manifest marks as only for no_std builds. The manifest also exposes opentype-layout for the GDEF, GPOS, GSUB and MATH tables and apple-layout for ankr, feat and format1 subtables in kern, kerx, morx and trak. There is a further option to parse individual TrueType tables separately, without loading the whole face.
Why a depth limit is not enough for composite glyphs
The most interesting piece of engineering in the README is the explanation of how recursive parsing is bounded. All recursive methods have a depth limit. But the documentation is explicit that a depth limit alone does not bound the work, because with fan-out b and depth d a small font can force b^d visits without ever exceeding the depth. So the methods whose input forms a graph, namely composite glyphs, the COLRv1 paint graph and CFF subroutines, additionally bound the total work per call. Stack usage is bounded too, though not tightly: outlining a composite variable glyph nests up to 32 frames, each holding a variation-tuple buffer, giving roughly 80KiB in the worst case. Arithmetic operations and numeric casts are mostly checked. This is the part of the design that separates a serious parser from a convenient one. A malformed font that references a composite glyph many levels deep is small on disk and expensive to expand, and the total-work bound is what stops it.
Maintenance mode, stated plainly in the README
The project documentation opens with a notice that the crate is in maintenance mode: bug fixes only, no new features. It says bug reports and fixes are welcome and will be reviewed promptly, and that correctness, panics and security issues are in scope. It then says explicitly that new table support, new API surface and performance work are not, and that feature requests will be closed. For new projects, the documentation recommends fontations from Google Fonts, naming the read-fonts and skrifa crates, describing it as actively developed with broader table support and as the direction the Rust font ecosystem is moving. The release history is consistent with that posture: the only listed release is v0.25.1, published on 2024-11-29, and the Cargo manifest still carries version 0.25.1. The last push was on 2026-08-06. That is a repository receiving fixes, not one gaining tables, so anyone planning around a table that does not exist yet should plan around fontations instead.
Getting the crate and reaching it from C
The distribution channel is crates.io, with API docs on docs.rs and the source in the repository. The manifest identifies the package as ttf-parser, version 0.25.1, with edition 2024 and a rust-version of 1.88.0, and Rust 1.88 and above is required with edition 2024. Those are the values you will write into your own manifest:
name = "ttf-parser"
version = "0.25.1"
edition = "2024"
rust-version = "1.88.0"The C side is a first class target rather than an afterthought. The repository has a top-level c-api/ directory and a meson.build file, the README mentions a basic C API, and The example programs live in examples/, including font-info.rs, font2svg.rs and a wasm/ subdirectory, and the wasm example matches the no_std and WASM compatibility claim. The manifest excludes benches, tests, testing-tools, examples and meson.build from the published package, so what you download from crates.io is the library alone, and the benchmark and test tooling stays in the repository.
The cases where ttf-parser is the wrong choice
Two boundaries are explicit. First, feature scope: the maintenance notice places new table support outside what will be accepted, so a team that needs a table the crate does not read today has no upgrade path here. Second, work scope: performance improvements are not in scope either, which matters if your workload is dominated by parsing throughput rather than by safety properties. The alternative named in the README is fontations, with the read-fonts and skrifa crates from Google Fonts, described as actively developed, with broader table support, and as the direction the Rust font ecosystem is moving. The difference in approach is a difference in project posture rather than in API shape: ttf-parser optimizes for zero allocation, zero unsafe and a stable surface that will not change, while fontations trades that freeze for ongoing development. If you are starting greenfield and need the wider table coverage, the project itself directs you elsewhere.
Licensing, contribution rules and the cost of a patch
The crate is offered under a dual licence: Apache License 2.0 or the MIT licence, at your option, matching the manifest field license = "MIT OR Apache-2.0". The repository ships LICENSE-APACHE and LICENSE-MIT files side by side. Any contribution submitted for inclusion is dual licensed under the same terms unless the author says otherwise. The licence choice carries no obligation to open source a program that links the library. The cost side of a patch is spelled out in CONTRIBUTING.md, which covers building and testing the library, the C API and the benchmarks, the lint and formatting workflow, and what is expected of a change to a parser of untrusted input. That last point is the one to read before proposing anything: a change to how tables are resolved or how recursion is bounded affects the security contract the crate advertises, and the documentation says correctness, panic and security fixes are the accepted categories.
Editorial conclusion
Use ttf-parser when you need to read untrusted font data in Rust or C under a hard memory and panic budget, for example inside a server that accepts uploaded fonts. Do not start a new project on it: the crate is in maintenance mode, the README says new table support and performance work are out of scope, and it points new users to fontations. Before committing, check whether the tables you actually need are covered by the feature set you enable, since disabling the default flags changes both the binary size and the API available to you.
Frequently asked questions
Is ttf-parser still actively developed?
The README states that the crate is in maintenance mode and takes bug fixes only, with no new features, new API surface or performance work. It recommends fontations from Google Fonts for new projects, and the last push was on 2026-08-06.
Does ttf-parser allocate memory or use unsafe Rust?
No. The README lists zero heap allocations, zero unsafe and zero dependencies among the crate's features, states that the library forbids unsafe code, and says that because there are no heap allocations a crash due to out of memory is not possible. It also states the library must not panic.
What Rust version and Cargo features does ttf-parser need?
The README requires Rust 1.88 and edition 2024, and the manifest sets rust-version = "1.88.0". The default features are std, alloc, opentype-layout, apple-layout, variable-fonts and glyph-names, and each can be disabled to reduce binary size.
Can ttf-parser be used from C?
Yes. The README mentions a basic C API, and the repository contains a c-api/ directory plus a meson.build file for those consumers. The C API is built and tested as part of the workflow described in CONTRIBUTING.md.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/harfbuzz-ttf-parser)Was this useful?