ExRatatui

Hex.pmDocsCILicense

Elixir bindings for the Rust ratatui terminal UI library, via Rustler NIFs.

Build rich terminal UIs in Elixir with ratatui's layout engine, widget library, and styling system together with the BEAM superpowers.

ExRatatui Demo

Features

Installation

Add ex_ratatui to the dependencies in mix.exs:

def deps do
[
{:ex_ratatui, "~> 0.10"}
]
end

Then fetch and compile:

mix deps.get && mix compile

A precompiled NIF binary for the host platform is downloaded automatically. The native library itself is loaded lazily on first use, so compiling a project that depends on ex_ratatui does not require the NIF to be loaded into the compiler VM.

Prerequisites

Precompiled NIF binaries are available for Linux (x86_64, aarch64, armv6/hf, riscv64), macOS (x86_64, aarch64), and Windows (x86_64). No Rust toolchain needed.

To compile from source instead, install the Rust toolchain and set:

export EX_RATATUI_BUILD=true

Quick Start

alias ExRatatui.Layout.Rect
alias ExRatatui.Style
alias ExRatatui.Widgets.{Block, Paragraph}
ExRatatui.run(fn terminal ->
{w, h} = ExRatatui.terminal_size()
paragraph = %Paragraph{
text: "Hello from ExRatatui!\n\nPress any key to exit.",
style: %Style{fg: :green, modifiers: [:bold]},
alignment: :center,
block: %Block{
title: " Hello World ",
borders: [:all],
border_type: :rounded,
border_style: %Style{fg: :cyan}
}
}
ExRatatui.draw(terminal, [{paragraph, %Rect{x: 0, y: 0, width: w, height: h}}])
# Wait for a keypress, then exit
ExRatatui.poll_event(60_000)
end)

Try the examples catalog for more — every widget has a focused, copyable demo, e.g. mix run examples/basics/hello_world.exs.

New here? The Getting Started guide builds a supervised todo app from mix new to a working TUI.

Runtimes and Transports

ExRatatui offers two ways to structure a supervised app and several ways to serve it — every combination works, and switching transport doesn't change the app module.

Guides

GuideDescription
Getting StartedWalk-through from mix new to a supervised TUI — the place to start
Building UIsWidgets, layout, styles, rich text, and events — everything for render/2
Custom WidgetsCompose primitives into reusable widgets via the ExRatatui.Widget protocol
ImagesImage rendering across terminals and transports — protocols, resizing, telemetry
Paste and ClipboardBracketed paste behaviour, batch-insert helpers, and an OSC 52 copy snippet
Callback RuntimeOTP-supervised apps with mount, render, handle_event, and handle_info callbacks
Reducer RuntimeElm-style apps with init, update, subscriptions, commands, and runtime inspection
State Machine PatternsMulti-screen apps, modals, and conditional UI without the tangle
TransportsCanonical feature matrix — what works where across Local / Session / SSH / Distributed / CellSession
Running TUIs over SSHServe any app as a remote TUI over SSH, standalone or under nerves_ssh
Running TUIs over Erlang DistributionDrive a TUI from a remote BEAM node with zero NIF on the app side
Custom TransportsPlug in a custom transport (TCP, Livebook, WebSocket) via the ExRatatui.Transport behaviour
Rendering to Non-Terminal SurfacesUse ExRatatui.CellSession to expose the rendered cell buffer to LiveView, framebuffers, screenshot tools, and other non-ANSI consumers
ArchitectureThe NIF bridge and the per-transport process trees
TestingHeadless backend, test_mode, inject_event, and assertion patterns
DebuggingRuntime.snapshot, tracing, buffer inspection, and common errors
PerformanceRender-loop tuning, render?: false, large trees, async effects
Telemetry:telemetry events for runtime, render, transport, and session — logging, metrics, OpenTelemetry
Widgets CheatsheetOne-page reference with every struct and its key fields

How It Works

ExRatatui bridges Elixir and Rust through Rustler NIFs: widget structs are encoded across the NIF boundary and decoded into ratatui types for rendering, while terminal events are polled on BEAM's DirtyIo scheduler so nothing blocks Elixir processes. Every transport builds on the same supervised Server process, with full session isolation per connected client.

The Architecture guide has the full picture — the NIF bridge and the per-transport process trees.

Ecosystem

Built with ExRatatui

Contributing

Contributions are welcome! See CONTRIBUTING.md for development setup and PR guidelines.

License

MIT — see LICENSE for details.