pty
A minimal, dependency-free Go library for opening and managing Unix pseudo-terminals.
Repository Health
Technical Analysis
pty gives Go programs direct access to Unix pseudo-terminals, letting a process spawn a child command — a shell, an interactive CLI, anything — attached to a real tty rather than a plain pipe. This matters whenever code needs to observe or drive a program that changes behavior based on whether it thinks it’s talking to a terminal: colored output, progress bars, password prompts, or full-screen TUIs like vim and top.
The package wraps the platform-specific ioctl calls needed to open a ptmx/pts pair, start a command attached to it via os/exec, and keep the terminal window size in sync via SIGWINCH forwarding. It has zero external dependencies and ships native implementations for Linux, Darwin, the BSDs, Solaris, and z/OS, falling back to a clear ErrUnsupported on Windows and other unsupported platforms.
What You Get
- A single Open() call that returns matching pty/tty *os.File pairs on Linux, Darwin, the BSDs, Solaris, and z/OS.
- Start / StartWithSize / StartWithAttrs helpers that wire an *exec.Cmd’s stdin/stdout/stderr to the tty side and set session/controlling-terminal flags for you.
- Window-size helpers (Getsize, GetsizeFull, Setsize, InheritSize) for keeping a pty’s dimensions in sync with a real terminal via SIGWINCH.
- Zero third-party dependencies — only Go’s standard library and direct syscalls.
Common Use Cases
- Terminal multiplexers and session managers — tools like tmux-style wrappers or SSH session proxies use pty to give a shell a real controlling terminal so job control and signals work.
- Recording and replaying terminal sessions — CLI recording tools attach a pty to a child process to capture exactly what would have appeared on a real terminal, including cursor codes.
- Testing CLI tools that behave differently under a tty — test harnesses spawn the binary under test through pty.Start so it takes the interactive code path instead of falling back to plain-pipe behavior.
- Web-based terminal emulators — servers that expose a shell over a websocket use pty to run the shell process and pipe pty output to/from the browser terminal.
Under The Hood
Architecture
pty is organized around a single narrow contract: each supported platform implements an unexported open() (pty, tty *os.File, err error) function behind a Go build tag, and the public API in doc.go (Open()) and start.go/run.go (Start, StartWithSize, StartWithAttrs) is entirely platform-agnostic on top of it. Platform files (pty_linux.go, pty_darwin.go, pty_freebsd.go, pty_dragonfly.go, pty_netbsd.go, pty_openbsd.go, pty_solaris.go, pty_zos.go, pty_unsupported.go) each implement the ptmx-open/grantpt/unlockpt/ptsname sequence using the OS’s own ioctls, while shared cross-cutting concerns — starting an *exec.Cmd on the tty side, propagating window size via Setsize/Getsize/InheritSize, and issuing raw ioctls through a SyscallConn-based, deadline-aware wrapper in ioctl.go — live in OS-independent files. There’s no dependency injection or interface layer because none is needed at this scope: it is a leaf utility with no internal state to swap, and changing the shared open() contract would require updating every platform file in lockstep, which is the expected cost of an OS-abstraction library this size.
Tech Stack
The module (go.mod) declares zero external dependencies and only requires Go 1.18, doing everything through the standard library’s os, os/exec, and syscall packages plus raw ioctl numbers defined per platform — there is no reliance on golang.org/x/sys or any third-party wrapper. A small amount of platform-specific Assembly (asm_solaris_amd64.s) backs Solaris support, and a Dockerfile.golang plus test_crosscompile.sh exist purely to verify the package builds across every supported GOOS/GOARCH combination. Linting is unusually thorough for a package this size: .golangci.yml runs an extensive, explicitly curated set of golangci-lint checks, with targeted //nolint annotations documenting each deliberate suppression rather than disabling rules wholesale.
Code Quality
Test coverage is real and platform-aware: doc_test.go and io_test.go exercise Open/Start round-trips, name resolution, window-size get/set, read deadlines, and the trickier case of Close() interrupting an in-flight Read() — using t.Parallel() and small custom assert/noError helpers rather than a heavyweight test framework. CI (.github/workflows/test.yml) runs the suite across ubuntu-latest and macos-latest against both the current and previous stable Go release, plus a deliberate sanity check on Go 1.6, and a separate crosscompile workflow builds the package for every supported target OS/architecture on every push. Error handling is explicit throughout — every syscall/ioctl result is checked and wrapped, and defer-based cleanup is annotated “Best effort” where errors are intentionally swallowed rather than silently ignored.
API Design pty doesn’t introduce a novel technique — pty allocation via ptmx/grantpt/unlockpt is the standard Unix mechanism, and the package’s value is in packaging that mechanism behind a minimal, dependency-free, cross-platform Go API rather than any new algorithm. The developer experience is deliberately small: Open() and Start() cover the common case in one call each, StartWithAttrs exists only for the rare case that needs to override SysProcAttr directly, and InheritSize is a two-line building block meant to be called from a SIGWINCH handler rather than a batteries-included resize manager. That minimalism, combined with zero dependencies and broad platform coverage, is why it has become a de facto pty implementation many higher-level Go terminal tools import rather than reimplement.
Used by 17 apps in this directory
hoop
Monitoring · Security
A wire-protocol gateway that enforces data masking, command blocking, approval workflows, and full session recording for engineers and AI agents accessing production infrastructure.
NetBird
Security
Replace your VPN with a zero-trust WireGuard overlay network that auto-connects devices, enforces SSO and posture checks, and deploys in under 5 minutes.
Okteto
Developer Tools · Devops
Develop applications directly inside your Kubernetes cluster with real-time file sync and instant hot-reload — no more docker build/redeploy cycles.
opencloud
File Storage
Open source file management and collaboration platform that keeps your data under your control, no database required.
OpenSandbox
Developer Tools · Security
Secure, fast, and extensible sandbox runtime for AI agents with multi-language SDKs and Docker/Kubernetes runtimes.
PostHog
Ab Testing Experimentation · Analytics · Developer Tools
The all-in-one open source product platform combining analytics, session replay, feature flags, error tracking, AI observability, and a built-in data warehouse in a single self-hostable stack.
sandboxd
Developer Tools · Devops
Self-hosted engine for AI app-builder products: give every user an isolated sandbox, a built-in coding agent, and a live preview URL — one command, no Kubernetes.
Teleport
Authentication · Security
Zero-trust infrastructure access platform that replaces credentials and VPNs with short-lived certificates, SSO, and identity-aware proxies for SSH, Kubernetes, databases, RDP, and AI agents.