5.9 KiB
nirc-rs 0.9.0: A Sovereign Data Terminal for the Modern Era
We just released nirc-rs 0.9.0 — a multi-protocol terminal chat client we call the "Sovereign Data Terminal." It's written in Rust, runs entirely in your terminal, and puts eight chat protocols behind a single interface. No web browsers, no Electron, no JavaScript runtime — just a binary and an SSH session.
Why We Built It
nirc-rs descends spiritually from naim, the terminal AIM/ICQ/IRC client from the late 1990s that many of us grew up with. naim had a philosophy: one terminal window, all your chat networks, zero graphical dependencies. We loved that philosophy, but the world moved on. naim's codebase stayed stuck in C89, its protocol support stopped at IRC and the now-defunct AIM/ICQ, and it couldn't handle TLS, E2EE, or modern protocols like Matrix and Discord.
We wanted that same experience back — a TUI client that treats every protocol as a first-class citizen — but built on modern foundations. Rust for memory safety and async I/O. ratatui for the terminal UI. rustls for TLS without OpenSSL. libp2p for peer-to-peer. The result is a ~10,000-line codebase across 27 source files that feels like naim's successor, not its clone.
Architecture
nirc-rs is structured around a multi-protocol dispatcher. Each protocol (IRC, ADC/DC++, Matrix, Discord, Stout, Spacebar, Nerimity, BitChat) implements a common trait and feeds messages into a unified ChatMessage type. The TUI layer doesn't care which protocol a message came from — it renders it the same way, with color-coded timestamps and protocol badges.
The async runtime is tokio with multi-threaded scheduling. File transfers run over yamux-multiplexed streams with 256 KiB buffers and in-flight SHA-256 verification. The identity vault uses AES-256-GCM encryption with Argon2id key derivation. Matrix's megolm E2EE runs on a dedicated OS thread because the matrix-sdk crypto types aren't Send — a necessary compromise that we handle transparently.
What's New in 0.9.0
This release focused on navigation and discoverability. We added Ctrl-P (previous buffer), Ctrl-A (next active buffer), and Ctrl-Z (highlight word cycling) for faster window management. The Insert key now scrolls to the bottom of chat and re-enables auto-scroll — a small quality-of-life improvement that saves constant PgDn mashing.
The biggest UI change is the F1 dropdown menu. Inspired by QBasic 4.5's menu system and aptitude's TUI menus, it provides a visual, navigable command tree. If you can't remember whether it's /whois or /wi, just press F1 and find it. This replaced the old Quake-style debug console binding, which we're reassigning in a future patch.
The transfer ticker now shows real-time speed and ETA in the footer bar, so you don't need to toggle a separate panel to see how your file transfers are progressing. We also fixed /nick to update all tab titles immediately and added the local IP address to the status bar.
The Tested Frontier: IRC and ADC/DC++
Two protocols are battle-tested in 0.9.0: IRC and ADC/DC++.
IRC has full TLS support via rustls, SASL PLAIN authentication, CTCP auto-response, ISUPPORT negotiation, and operator commands. It connects to Libera, OFTC, and other networks without issue. ADC/DC++ connects to hubs, performs the HSUP/HSID/INF handshake, supports hub search, and handles file transfers with the full yamux-multiplexed pipeline. ADC also has a varnish-style security guard pipeline that does rate limiting, IP validation, SSRF prevention, and path traversal blocking.
The Untested Frontier
Six protocols are fully implemented in the codebase but haven't been tested against live servers yet: Matrix (with megolm E2EE via matrix-sdk 0.18), Discord (Gateway WebSocket), Stout and Spacebar (Revolt-compatible forks), Nerimity (a custom platform), and BitChat (P2P over libp2p with mDNS discovery and gossipsub).
These aren't stubs or skeleton implementations — they're complete protocol handlers with connection management, message parsing, event dispatch, and TUI integration. They just need someone to point them at a real server and verify the wire protocol matches reality. That's the top priority for the next release cycle.
Security
We take the "sovereign" part seriously. nirc-rs never phones home. There's no telemetry, no analytics, no update checker. The identity vault encrypts credentials with AES-256-GCM and Argon2id (64 MiB memory, 3 iterations), and keys are zeroed from RAM on lock via the zeroize crate. ADC connections go through a guard pipeline that rejects private IPs, blocks path traversal, and prevents SSRF. TLS is handled by rustls with the webpki-roots CA bundle — no system OpenSSL needed.
Build It
git clone https://git.dcos.net/dcosnet/nirc-rs.git
cd nirc-rs
cargo build --release
./target/release/nirc-rs
That's it. One binary, no runtime dependencies beyond your terminal emulator. Config lives at ~/.nirc/config.toml and is created automatically on first run. Full documentation is in the README and quick-start guide.
What's Next
The roadmap for 0.10.0 and beyond is straightforward: test the six untested protocols, fix ADC CID generation to use proper Base32/Tiger hashes, integrate the transfer widget into the main draw loop, and add IRC SASL EXTERNAL with client certificates. We're aiming for a 1.0.0 release once all eight protocols are verified against live servers and the plugin API has a stability guarantee.
If you want to help test a protocol, write a plugin, or contribute a patch, the repository is at git.dcos.net/dcosnet/nirc-rs. It's GPL-3.0-or-later, and we welcome contributions.
nirc-rs 0.9.0 is available now. cargo install nirc-rs or build from source. Your terminal, your data, your protocols.