jjenkins
Drafter - Build rich terminal UIs in Elixir, locally or over SSH
I’ve been working on a TUI framework for Elixir called Drafter, inspired by Python’s Textual but built around Elixir idioms — declarative rendering, pattern-matched event handling, and OTP-native architecture.
The basic idea:
Mix.install([{:drafter, "~> 0.1.3"}])
defmodule CounterApp do
use Drafter.App
def mount(_props), do: %{count: 0}
def render(state) do
vertical([
header("Counter"),
label("Count: #{state.count}", flex: 1),
horizontal([
button("−", on_click: :dec),
button("+", on_click: :inc)
], gap: 2),
footer(bindings: [{"q", "Quit"}])
])
end
def handle_event(:inc, _data, state), do: {:ok, %{state | count: state.count + 1}}
def handle_event(:dec, _data, state), do: {:ok, %{state | count: state.count - 1}}
def handle_event({:key, :q}, _state), do: {:stop, :normal}
def handle_event(_event, state), do: {:noreply, state}
end
Drafter.run(CounterApp)
What’s in the box:
- 30+ widgets — DataTable, Tree, Charts, TextInput, TextArea, Checkbox, RadioSet, Markdown, CodeView, and more
- Flexible layouts — vertical, horizontal, grid, scrollable, sidebar
- Multi-screen navigation — push/pop screens, modals, popovers, panels, toasts
- Theming system with HSL/RGB/hex color support
- Declarative widget event handling with automatic focus management
- DOM-like three-phase event system (capture → target → bubble)
- Animation engine with 30+ easing functions
- Syntax highlighting via tree-sitter (optional)
- Headless testing harness for ExUnit
- Many examples
TUI over SSH:
Drafter.Server.start_ssh(ChatApp,
port: 2222,
mode: :shared,
auth: [{"alice", "pass"}, {"bob", "pass"}]
)
Any standard SSH client connects and gets a full interactive TUI session. :shared mode means all connected clients see the same state — input from any client updates everyone’s view in real time. The included ssh_chat.exs example is a working multi-user chat app you can try in a couple of minutes.
Built on OTP 28 — raw terminal mode, proper Unicode, and lazy input reading. Earlier OTP versions won’t work correctly.
Feedback and contributions welcome. Still early, but it’s been running real apps reliably.
Most Liked
fuelen
It looks interesting. I’m wondering how it differs from https://github.com/pcharbon70/term_ui ?
jjenkins
Thanks!
I’m hoping we see some nice Elixir/beam TUI apps, as well as any feedback for improvements, or any additions.
i will, hopefully soon, drop my heavily WIP project that rides on top of it. Grafana TUI client.
Just need to generate some sharable pics.
jjenkins
Thanks For pointing that out. I had gone through all of the TUI libraries I could find for Elixir (and checked other ecosystems) before starting on my own library.
I’ve taken a look at term_ui and really like a number of the widgets, and the clean simplicity. I would ask that you try out all of the examples from both projeccts. I know that Drafter is still very much a WIP, but it’s getting there.
There are a number of things we do differently, including colors, themes, animations, mouse support, etc.
I may look to borrow some of the themes/ideas of term_ui as I continue to work on Drafter.
Please let me know what you think after trying both.
Thanks.
Popular in Announcing
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









