5.0 KiB
Executable File
nirc-rs 0.9.0
I just released nirc-rs 0.9.0 — a multi-protocol terminal chat client I wrote in Rust. It 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 a terminal.
Why I Built It
nirc-rs descends from naim, the terminal AIM/ICQ/IRC client from the late 1990s. naim had a simple idea: one terminal window, all your chat networks, zero graphical dependencies. I liked that idea, 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.
I 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 roughly 10,000 lines across 27 source files.
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 I handle transparently.
What's New in 0.9.0
This release focused on navigation and discoverability. I 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.
The biggest UI change is the F1 dropdown menu. It provides a visual, navigable command tree. If you can't remember whether it's /whois or /wi, press F1 and find it. This replaced the old debug console binding, which I'm 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. I 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 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 — they're complete protocol handlers with connection management, message parsing, event dispatch, and TUI integration. They just need to be pointed at a real server to verify the wire protocol matches reality. That's the top priority for the next release cycle.
Security
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
One binary, no runtime dependencies beyond your terminal emulator. Config lives at ~/.nirc/config.toml and is created automatically on first run.
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. I'm 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 contributions are welcome.