Repartee
A modern terminal IRC client built with Rust, Ratatui, and Tokio.
Inspired by irssi. Designed for the future.
Demo
Terminal, mobile web, and desktop web — all in real-time sync:
TUI (left) | Mobile web (center) | Desktop web (right) — 1:1 state sync across all interfaces.
Features
- Full IRC protocol — channels, queries, CTCP, TLS, channel modes, ban/except/invex lists
- IRCv3 — server-time, echo-message, away-notify, account-notify, chghost, multi-prefix, BATCH netsplit grouping, message-tags, and more
- SASL — PLAIN, EXTERNAL (client certificate), and SCRAM-SHA-256
- irssi-style navigation — Esc+1–9 window switching, aliases, familiar
/commands - Mouse support — click buffers and nicks, scroll chat history
- Lua 5.4 scripting — event bus, custom commands, full IRC and state access, sandboxed per-script environments
- Persistent logging — SQLite with WAL, FTS5 full-text search, optional AES-256-GCM encryption
- Netsplit detection — batches join/part floods into single events
- Flood protection — blocks CTCP spam and nick-change floods automatically
- Nick coloring — deterministic per-nick colors (WeeChat-style) with HSL hue wheel for truecolor, 256-color and 16-color fallbacks, auto-detected terminal capability, configurable saturation/lightness
- Theming — irssi-compatible format strings with 24-bit color support and custom abstracts
- Web frontend — built-in HTTPS web UI with mobile support, real-time sync with the terminal, swipe gestures, 5 themes
- DCC CHAT — direct client-to-client messaging with active and passive (reverse) connections
- Spell check — inline correction with Hunspell dictionaries, multilingual, Tab to cycle suggestions, computing/IT dictionary with 7,400+ terms, replace and highlight modes
- Embedded shell — full PTY terminal inside Repartee (
/shell) — run vim, btop, irssi without leaving the client. Also available in the web frontend via beamterm WebGL2 renderer with Nerd Font, mouse selection, Ctrl+/- font resize, and clipboard paste - Detach & reattach — detach from your terminal and reattach later; IRC connections stay alive
- Extban —
$a:accountban type with/ban -ashorthand - Single binary — ~20MB (SQLite, Lua, and WASM frontend bundled). Runtime dependency:
libchafa(image rendering)
Installation
Pre-built binaries
Download from GitHub Releases:
| Platform | Binary |
|---|---|
| macOS ARM64 | repartee-macos-arm64.tar.gz |
| Linux x86_64 | repartee-linux-amd64.tar.gz |
| Linux ARM64 | repartee-linux-arm64.tar.gz |
| FreeBSD x86_64 | repartee-freebsd-amd64.tar.gz |
From crates.io
From source
Requirements
- Runtime:
libchafa>= 1.8.0 (image rendering) —brew install chafa/apt install libchafa-dev/pkg install chafa - Build: Rust 1.85+ (2024 edition) — install via rustup
- A terminal with 256-color or truecolor support (iTerm2, Alacritty, kitty, WezTerm, Ghostty, Subterm, etc.)
- A modern web browser for the web frontend (optional)
Quick Start
Launch repartee:
Add a server and connect:
/server add libera irc.libera.chat
/connect libera
/join #repartee
Or edit ~/.repartee/config.toml directly:
[]
= "Libera"
= "irc.libera.chat"
= 6697
= true
= true
= ["#repartee"]
Key Bindings
| Key | Action |
|---|---|
Esc + 1–9 |
Switch to buffer |
Ctrl+N / Ctrl+P |
Next / previous buffer |
Tab |
Nick completion |
Up / Down |
Input history |
Mouse click |
Select buffer or nick |
Mouse wheel |
Scroll chat |
Ctrl+] |
Exit shell input mode |
Ctrl+Z |
Detach from terminal |
/detach or /dt |
Detach from terminal |
Directory Layout
~/.repartee/
config.toml # main configuration
.env # credentials (SASL passwords, log encryption key)
themes/ # custom .theme files
scripts/ # Lua scripts
logs/messages.db # chat logs (SQLite)
sessions/ # Unix sockets for detached sessions
Sessions & Detach
repartee can run in the background while you close your terminal:
# Detach: press Ctrl+Z or type /detach — terminal is restored
# Reattach from any terminal:
# Or start headless (no terminal needed):
Everything survives detach — IRC connections, scrollback, scripts, and channel state.
Scripting
Scripts are Lua 5.4 files placed in ~/.repartee/scripts/:
meta =
Load at runtime:
/script load hello
Or autoload in config:
[]
= ["hello"]
Theming
Themes are TOML files in ~/.repartee/themes/ using irssi-compatible format strings with 24-bit color extensions:
[]
= "1a1b26"
= "a9b1d6"
= "e0af68"
= "7aa2f7"
[]
= "{pubmsgnick $0}$1"
= "{ownmsgnick $0}$1"
Set the active theme:
[]
= "mytheme"
Documentation
Full documentation is available at repart.ee/docs.
- Installation
- Quick Start
- Configuration
- Themes
- Commands
- Web Frontend
- Sessions & Detach
- Lua Scripting
- Lua API Reference
- Logging & Search
Changelog
v0.8.5
- Critical: fix 3 GB OOM crash on long mouse-wheel scroll — the chat view's render loop could walk the entire message buffer on every frame when
scroll_offsetexceeded available content. Under sustained wheel scrolling this produced 200–600 MB/s of allocation churn, fragmenting glibc's arena until the kernel (orsystemd-oomd) killed the process at ~3 GB RSS. The loop is now capped atbuffer_len × 16visual lines so it terminates inO(buffer_len)regardless of scroll position. Observed on Debian with v0.8.4 after a week of uptime; pre-existing bug, not a 0.8.4 regression, but v0.8.4 had enough baseline churn to make it reachable in normal use. - jemalloc on Linux —
tikv-jemallocatoris now the global allocator on Linux builds via#[cfg(target_os = "linux")]. Defense-in-depth against glibc ptmalloc2 fragmentation in long-running sessions (weeks of uptime). macOS keepslibsystem_malloc, FreeBSD keeps its native jemalloc — builds on those platforms are byte-identical to v0.8.4, the dependency is not pulled into their build graph at all. - Regression tests — six unit tests lock in the render-budget invariant so the OOM cannot regress silently; tests are organized under
compute_render_budget::...for IDE filtering and carry diagnostic assert messages.
v0.8.4
- Web: sticky scroll — auto-scroll now only scrolls to bottom when you're already there; scroll-up to read backlog stays put. Scroll-to-bottom button (▼) appears when scrolled up
- Web: event_key parity — web frontend now receives per-event-type keys (join, part, quit, kick, kicked, nick_change, topic_changed, mode, connected, disconnected, chghost, account) for themed icons and colors instead of fragile text heuristics
- Web: notice rendering — notices now render with
-nick- textformat and distinct cyan styling - Web: nick truncation — accounts for mode prefix width (
@,+) like the TUI does - Kick notification — when kicked from a channel, the message now appears in the server status window, the channel buffer (before removal), and the landing buffer (where you end up). Themed as
kickedevent with red highlight /kickand/kbaccept#channel— you can now specify a target channel:/kick #otherchan nick reason- Web: in-memory FetchMessages — initial buffer loads serve from in-memory messages first, ensuring recent events (like kick notifications) are visible immediately even before the log writer flushes to SQLite
event_keypersisted to DB — backward-compatible migration addsevent_key TEXTcolumn so historical messages retain their event type for themed rendering- CI: WASM build step — release workflow now builds the WASM frontend in a separate job, ensuring every release binary includes the latest web UI
- Removed dead
MessageType::Ctcpvariant
v0.8.3
- Web buffer sync reliability fixes
License
MIT — see LICENSE.
