portable-pty

Cross-platform Rust API for pseudo-terminals, with runtime-selectable implementations

Library
Cargo
v0.9.0
28,435stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
91/100Excellent
Development Activity100
Maintenance96
Community68
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
81/100Excellent
Architecture86
Code Quality80
Innovation82
Learning Curve76

portable-pty is the cross-platform pseudo-terminal (pty) abstraction extracted from the WezTerm terminal emulator’s monorepo. It provides PtySystem/PtyPair traits for opening a pty and spawning a child process attached to it, unifying Unix openpty/forkpty semantics and the Windows ConPTY API behind one interface, with an additional serial module for talking to physical or virtual serial ports using the same pty-like traits.

Unlike most pty crates that hard-code a single platform backend, portable-pty is explicitly designed to let callers select an implementation at runtime via trait objects (Box<dyn PtySystem>), which is what lets WezTerm itself support Unix ptys, Windows ConPTY, and even serial-port ‘ptys’ through the same terminal-multiplexer code paths. It’s published independently on crates.io and widely reused by other terminal and shell-integration tooling beyond WezTerm itself.

What You Get

  • native_pty_system() to get the right pty backend (Unix pty, Windows ConPTY) for the current platform behind a common trait object
  • PtyPair with master/slave handles for reading/writing pty output and spawning a command into the slave side
  • CommandBuilder for constructing the child process command, arguments, environment, and working directory to spawn into the pty
  • A serial module exposing the same pty-like read/write traits over physical or virtual serial ports
  • Optional serde_support feature for serializing pty configuration types

Common Use Cases

  • Building a terminal emulator or terminal multiplexer that needs to spawn and manage shell processes across Unix and Windows
  • Writing a Rust-based shell integration, REPL wrapper, or automation tool that needs true pty semantics (not just piped stdio) for interactive programs
  • Testing CLI tools that behave differently under a tty versus a pipe, by driving them through a real pseudo-terminal
  • Implementing serial-port communication tooling that can share code paths with pty-based terminal logic

Under The Hood

Architecture - lib.rs defines the platform-agnostic PtySystem/PtyPair/MasterPty/SlavePty trait hierarchy and a native_pty_system() factory that returns the appropriate backend; unix.rs implements the Unix side via openpty/fork-style syscalls (through nix/libc), a win/ module implements the Windows ConPTY backend, and cmdbuilder.rs provides a cross-platform command/argument/environment builder used to spawn the child process into the pty. Tech Stack - Rust 2018 edition with nix (term/fs features) and libc for Unix syscalls, winapi/winreg/shared_library for the Windows ConPTY path, filedescriptor for cross-platform fd handling, serial2 for the serial-port module, and workspace-inherited dependency versions shared across the wider wezterm monorepo. Code Quality - The crate ships runnable examples/ (bash.rs, whoami.rs, whoami_async.rs, narrow.rs) demonstrating real spawn/read/write usage across sync and async (via smol) code paths, and benefits from WezTerm’s very active, heavily-tested monorepo CI (21+ commits/month, 435 contributors) even though the crate itself has no dedicated unit-test directory — correctness is largely validated through WezTerm’s own end-to-end usage. API Design - The runtime-selectable trait-object design (Box<dyn PtySystem>) is the crate’s key differentiator versus compile-time-only pty bindings, and the doc-comment example at the top of lib.rs covers the full open-spawn-read-write lifecycle in under 15 lines, keeping the common case simple despite the cross-platform abstraction underneath.

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