Crossterm: A Pure-Rust Terminal Library That Puts Windows 7 on the Map
Cross platform terminal library rust. It supports all UNIX and Windows terminals down to Windows 7 (not all terminals are tested, see Tested Terminals for more info).
At a glance
- What is it?
- Crossterm is a cross-platform terminal manipulation library for Rust, supporting everything from Windows 7 consoles to modern Unix terminals. It offers cursor control, styled output, and event handling, but its real value is in how it balances feature coverage with a surprisingly small dependency footprint.
- Who is it for?
- Adopt crossterm if you need a single Rust dependency for terminal manipulation that works across Unix and Windows, including older Windows 7 systems, and you want fine-grained control over cursor, color, and input events. Skip it if you need a full widget toolkit or if your target terminal is not in the tested list, such as exotic emulators or unusual Unix configurations.
- Can I use it commercially?
- Yes. MIT 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 2 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 September 14, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The Problem: Terminal Code Is Still a Platform Mess
Writing terminal interfaces in Rust usually means hitting the wall of platform differences. Unix terminals speak ANSI escape sequences, but Windows consoles, especially pre-Windows 10, have their own APIs. Most libraries either target Unix only or wrap a C library, which brings its own portability headaches. Crossterm aims to be a pure-Rust answer: one crate that handles cursor movement, styled output, terminal queries, and input events on both Unix and Windows, down to Windows 7. The README is explicit that not all terminals are tested, but the promise is broad coverage for a language that often gets pushed into systems programming where the terminal is an afterthought. This is for developers building text-based interfaces, like TUIs, REPLs, or logging tools, who do not want to maintain separate code paths for each operating system.
How Crossterm Structures Its API
The crate is organized into three main areas: cursor, style, and terminal, plus an event module. Commands like SetForegroundColor and Print are types that implement a trait, and you can execute them either via a macro or as methods on a writer. The README shows both forms: execute!(stdout(), SetForegroundColor(Color::Blue), Print("Styled text here.")) or chaining .execute() calls. This design gives you full control over when the output buffer is flushed, which is a deliberate choice for performance-sensitive applications. The event system is separate, offering poll and read APIs, and optionally a futures Stream when you enable the event-stream feature. Mouse events include press, release, position, button, and drag, with modifier key support for SHIFT, ALT, and CTRL. The architecture is straightforward: commands write escape sequences or call platform-specific functions, and events are polled through a backend that can be swapped.
Getting It Running: Cargo and Feature Flags
Adding crossterm is a simple line in Cargo.toml: crossterm = "0.27". That pulls in the default features, which include events. If you want async event streaming, you enable the event-stream feature. There is also serde for serializing events, derive-more for is_* helper methods, and osc52 for clipboard support via crossterm::clipboard. The README highlights a way to trim the dependency tree: disabling the events feature or using the filedescriptor feature removes mio, signal-hook, and signal-hook-mio, leaving a thinner layer. That is useful if you only need cursor and style commands and want to avoid the overhead of an event loop. The feature flags are documented in a table, so you can see exactly what each one adds. The examples directory is referenced for more advanced usage, though the README only shows a basic styling example.
Dependency Footprint: Justified or Overkill?
The README includes a dependency justification table, which is a rare and welcome transparency. It lists each dependency and what it is for. bitflags handles KeyModifiers, parking_lot provides locking with timeouts, and libc is used for low-level Unix functions. Mio and signal-hook are optional and only included with the events feature on Unix. winapi is Windows-only. This is a deliberate attempt to keep the core small. For a library that claims few dependencies, the list is reasonable, but it is not zero. If you are building a minimal tool that only outputs colored text, you might not need all of this. The option to disable events is a practical way to cut most of it out. That said, you still get parking_lot and bitflags, which are small but not trivial. The trade-off is that you get a uniform API across platforms, which is worth something.
Where Crossterm Falls Short
The biggest limitation is the tested terminals list. It covers Windows 10 and 11 consoles, Windows Terminal, GNOME Terminal, Konsole, Kitty, Alacritty, and a few macOS terminals. That is a solid set, but it is not exhaustive. The README admits that not all terminals are tested, and it asks users to add their own to the list. That means if you target a niche terminal like a terminal emulator on a BSD or an older Unix variant, you are on your own. Another limitation is that some features are not universally supported, like cursor blinking. The README says not all terminals support it, so you need to handle failures gracefully. Also, the library does not provide a full TUI framework; it is low-level. You get commands and events, but no widgets, layouts, or event loop. You have to build those yourself, which is fine for simple tools but a lot of work for complex interfaces.
Alternatives: The Unix-Only and Full-Framework Paths
The obvious alternative is the termion crate, which is also pure Rust but Unix-only. Termion does not support Windows at all, so if you need cross-platform, crossterm is the choice. On the other end, there is tui-rs (now ratatui), which builds on top of a terminal backend like crossterm or termion and provides a widget system. That is the difference in approach: crossterm gives you the primitives, while ratatui gives you a higher-level canvas. If you want to write a dashboard with panels and lists, ratatui saves you time, but it adds a layer of abstraction and its own learning curve. Crossterm is better if you want direct control over every escape sequence and event, or if you need to support Windows 7, which ratatui may not handle as well depending on its backend. The choice comes down to whether you want to own the rendering logic or delegate it.
Maintenance and License Considerations
The project is actively maintained, with a release in April 2025 (version 0.29) and another in July 2024 (0.28). That is a recent push, which suggests the maintainers are responsive. The license is MIT, which is permissive and standard for Rust libraries. There are no obvious red flags in the repository, but the README mentions a deprecated examples repository, so you should rely on the docs.rs documentation for current examples. The feature flags have changed over versions, as seen from the version history, so upgrading from 0.27 to 0.28 or 0.29 may require adjusting your Cargo.toml if you use optional features. The dependency table is a good place to check for breaking changes. For a library that is a foundation for your own code, the maintenance cadence and license are favorable, but you should still pin a version and test after upgrades.
Editorial conclusion
Adopt crossterm if you need a single Rust dependency for terminal manipulation that works across Unix and Windows, including older Windows 7 systems, and you want fine-grained control over cursor, color, and input events. Skip it if you need a full widget toolkit or if your target terminal is not in the tested list, such as exotic emulators or unusual Unix configurations. Before committing, verify that your specific terminal behaves correctly with features like cursor blinking and RGB color, and check whether the 'event-stream' feature fits your async model. The library's own documentation and the tested terminals list are your first stop for that validation.
Community notes