cosmic-text

A pure Rust library for multi-line text shaping, layout, bidi, font fallback, and rendering used to build text widgets and editors.

Library
Cargo
v0.19.0
2,135stars
MIT OR Apache-2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
71/100Good
Development Activity64
Maintenance60
Community68
Maturity52
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
79/100Good
Architecture85
Code Quality82
Innovation78
Learning Curve70

cosmic-text is a pure Rust library that handles the full pipeline of getting text onto a screen: shaping, font discovery and fallback, bidirectional layout, and rasterization. It was built by System76 for the COSMIC desktop environment but is designed as a general-purpose text-handling crate for any Rust UI toolkit that needs more than simple monospace rendering.

Shaping is delegated to HarfRust (a Rust port of HarfBuzz), font discovery to fontdb, and glyph rasterization to swash, while layout, line wrapping, bidirectional text support, and font fallback are implemented directly in the crate. It ships a FontSystem for locating fonts, a Buffer for shaping and laying out UTF-8 text, and an Editor/Viewport-style API for building interactive multi-line text editing widgets, including cursor movement, selection, and optional vi-style keybindings.

The crate supports Linux, macOS, and Windows with the full feature set, exposes optional no_std builds for constrained environments, and is validated against a stress test that replays the Universal Declaration of Human Rights in roughly 500 languages through the editor pipeline to catch shaping and layout regressions across scripts.

What You Get

  • A FontSystem for discovering and loading system and bundled fonts via fontdb
  • A Buffer API for shaping and laying out UTF-8 text with word wrapping and per-span or per-buffer styling
  • Bidirectional text support (RTL/LTR) implemented directly in the crate, not delegated to an external shim
  • Automatic font fallback per line and per character, seeded from browser-style fallback lists (Chromium/Firefox)
  • An Editor type with cursor movement, text selection, undo/redo (via cosmic_undo_2), and optional vi-style modal editing
  • A SwashCache for rasterizing glyphs into images or pixels, with support for ligatures and color emoji
  • Optional no_std support for shaping and layout in constrained or embedded environments
  • Cargo feature flags to opt in/out of swash rendering, fontconfig, vi keybindings, and syntax highlighting via syntect

Common Use Cases

  • Rendering text in a custom Rust GUI toolkit or game engine without depending on a platform text API
  • Building a lightweight code or plain-text editor widget with cursor/selection handling
  • Rendering multi-script, bidirectional UI text (Arabic, Hebrew, CJK, Devanagari) correctly in a native application
  • Adding text shaping and font fallback to a no_std or embedded Rust UI
  • Powering the text stack of a desktop environment or window manager (as in COSMIC/Pop!_OS)

Under The Hood

Architecture cosmic-text is organized as a pipeline of composable stages rather than a monolithic renderer: FontSystem (font/mod.rs, font/system.rs, font/cache.rs) owns font discovery and caching via fontdb and exposes per-font harfrust::Shaper instances through a self_cell-backed OwnedFace wrapper that keeps borrowed shaping data alive alongside its owning buffer; shape.rs and shape_run_cache.rs turn styled text spans into shaped glyph runs, with results cached to avoid re-shaping unchanged text; layout.rs and buffer_line.rs/buffer.rs turn shaped runs into wrapped, positioned lines, consulting bidi_para.rs for bidirectional reordering; edit/mod.rs, edit/editor.rs, and edit/vi.rs layer cursor, selection, undo (via the optional cosmic_undo_2 crate), and vi-style modal editing on top of a Buffer; and render.rs/swash.rs bridge shaped/positioned glyphs to the optional swash rasterizer through SwashCache. This staged design lets a consumer stop at layout (for measurement-only use cases) or go all the way to rasterized pixels, and it means font loading, shaping, layout, and rendering can each be swapped or disabled via Cargo features without touching the others.

Tech Stack The crate is pure Rust with a deliberately thin, mostly-optional dependency set declared in Cargo.toml: harfrust (a Rust HarfBuzz port) for shaping, fontdb for font discovery/loading, skrifa for low-level font table access, swash (optional, on by default) for rasterization, unicode-bidi, unicode-linebreak, and unicode-script for Unicode-correct bidi and line-breaking behavior, rangemap and rustc-hash for internal span/lookup data structures, and optional syntect plus cosmic_undo_2 and modit gated behind the vi feature for syntax-highlighted, undoable, vi-style editing. Feature flags (std, no_std, fontconfig, swash, vi, wasm-web, shape-run-cache, peniko) let consumers tailor the build from a full desktop text stack down to a no_std shaping-and-layout-only footprint; CI runs cargo-deny for license/dependency auditing plus clippy with --all-features via a dedicated ci.sh script.

Code Quality The crate enables an unusually strict lint posture at the top of lib.rs: #![deny(clippy::unwrap_used)], #![deny(missing_debug_implementations)], #![deny(unreachable_patterns)], and #![deny(unused_must_use)], plus warn-level lints for undocumented panics/errors and unreadable literals, indicating deliberate attention to panic-safety and API documentation even though indexing_slicing and arithmetic_side_effects are explicitly allowed with a TODO to tighten them later. Correctness is exercised through a tests/ directory covering bidi direction, ellipsized rendering, rich-text layout, text decorations, variable font weights, and wrap stability/fallback behavior, plus Criterion benchmarks (benches/layout.rs, benches/text_shaping_benchmarks.rs) for shaping performance regressions, and a distinctive stress test (editor-test example) that replays the ~500-language Universal Declaration of Human Rights corpus character-by-character through the editor to catch shaping/layout bugs across scripts. Naming is consistent Rust convention throughout, and the public API surface is documented with a runnable doctest in lib.rs.

API Design The public API favors composability over convenience: a typical integration creates one FontSystem and one SwashCache per application, builds a Buffer from Metrics (font size/line height) and Attrs, calls set_text with a Shaping mode, then iterates layout_runs() for measurement or calls draw() with a per-pixel callback for rendering — all shown in a working doctest in lib.rs. This keeps the crate agnostic about how a consumer actually paints pixels (no assumed windowing or GPU backend), at the cost of requiring callers to wire up their own rendering callback and to understand the shape → layout → draw staging. Five runnable examples (editor, editor-test, multiview, rich-text, terminal) demonstrate integration patterns from a full interactive editor to a bare terminal renderer, lowering the ramp-up cost for a low-level crate.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search