Terminal built for your Gundam

raxol

OTP-native terminal framework for Elixir

{:raxol, "~> 2.3"}

Why OTP

Every capability below comes from the BEAM VM, not a library.

Capability Raxol Ratatui Bubble Tea Textual Ink
Crash isolation per component yes -- -- -- --
Hot code reload (no restart) yes -- -- -- --
Same app in terminal + browser yes -- -- partial --
Built-in SSH serving yes -- via lib -- --
AI agent runtime yes -- -- -- --
Distributed clustering (CRDTs) yes -- -- -- --
Time-travel debugging yes -- -- -- --

Ratatui and Bubble Tea have excellent rendering and large ecosystems. Raxol's advantage is structural: crash isolation, hot reload, distribution, and SSH come from OTP, not application code.

Hello World

Every Raxol app follows The Elm Architecture: init, update, view. Here's a counter in 20 lines.

counter.exs
defmodule Counter do
  use Raxol.Core.Runtime.Application

  @impl true
  def init(_ctx), do: %{count: 0}

  @impl true
  def update(:increment, model), do: {%{model | count: model.count + 1}, []}
  def update(:decrement, model), do: {%{model | count: model.count - 1}, []}
  def update(_, model), do: {model, []}

  @impl true
  def view(model) do
    column style: %{padding: 1, gap: 1} do
      [
        text("Count: #{model.count}", style: [:bold]),
        row style: %{gap: 1} do
          [button("Increment", on_click: :increment), button("Decrement", on_click: :decrement)]
        end
      ]
    end
  end

  @impl true
  def subscribe(_model), do: []
end

That counter works in a terminal. The same module renders in Phoenix LiveView. The same module serves over SSH. One codebase, three targets. See the full example with keyboard handling:

$ mix run examples/getting_started/counter.exs

What's in the box

Crash Isolation

Wrap any widget in process_component/2. It crashes, it restarts. Your UI keeps running.

Hot Code Reload

Change your view/1 function, save. The running app updates. No restart.

AI Agent Runtime

Agents are TEA apps where input comes from LLMs. Supervised, crash-isolated, streaming.

SSH Serving

Raxol.SSH.serve(MyApp, port: 2222). Each connection gets its own supervised process.

LiveView Bridge

Same TEA app renders to terminal and Phoenix LiveView. One codebase.

Distributed Swarm

CRDTs, node monitoring, elections. Discovery via gossip, DNS, or Tailscale.

Time-Travel Debug

Snapshot every update/2 cycle. Step back, forward, jump, restore.

29 Widgets

Buttons, tables, trees, charts, sparklines. Flexbox + CSS Grid layout.

Performance

On Apple M1 Pro (Elixir 1.19 / OTP 27). 13% of the 60fps budget.

What Time
Full frame (create + fill + diff) 2.1 ms
Tree diff (100 nodes) 4 μs
Cell write 0.97 μs
ANSI parse 38 μs

Standalone Packages

Use the full framework, or pick just the parts you need.

raxol_core

Behaviours, events, config, accessibility, plugins.

765 tests

raxol_terminal

VT100/ANSI emulation, screen buffer, termbox2 NIF.

1,874 tests

raxol_agent

AI agent framework. Supervised agents with LLM streaming.

131 tests

raxol_sensor

Sensor fusion. Zero dependencies.

55 tests

Try It

$ mix raxol.playground # 29 demos across 8 categories
$ ssh -p 2222 playground@raxol.io # same thing, over SSH
$ mix run examples/demo.exs # flagship BEAM dashboard
input display feedback navigation overlay layout visualization effects
Open Playground