Fallegji is a terminal-based P2P group chat app written in Rust. It's inspired by the Fallegha of north Africa who were responsible for the armed resistance against colonialism and operated in total secrecy. This app features:
- Zero-server and fully decentralized: No servers, no accounts, no intermediaries — every peer is a first-class node in a direct, full-mesh network, with no central point to seize, subpoena, or shut down.
- End-to-end encrypted by construction: Modern X25519 key exchange and ChaCha20-Poly1305 authenticated encryption protect every byte on the wire under unique pairwise keys. Plaintext never touches the network, and your history never leaves your machine.
- Runs over onion network, a VPN, or your LAN: pick your transport. Onion mode ships an in-process onion network client and gives the chat a stable, shareable
.onionrendezvous link that any member can host, so the group keeps working even when the admin is offline. LAN/VPN stays raw-TCP fast; onion trades a little latency for IP and metadata privacy. - Group chat that simply converges: Each peer holds its own embedded SQLite replica that reconciles automatically on join, rejoin, and recovery — an eventually-consistent, conflict-free design with no source of truth and no dropped messages.
- A network that heals itself: Heartbeat-driven presence, automatic re-dialing of lost peers, and transparent IP-change / NAT re-announcement keep conversations alive through roaming and reconnects, with zero manual intervention.
- A terminal experience that feels like home: Full Vim-modal editing — motions, operators, and counts — alongside a mouse-draggable scrollbar, desktop notifications, and fully themeable per-chat colors. Keyboard-first and unmistakably yours.
- Hardened against abuse from day one: Per-peer rate limiting, strict frame-size caps (anti-OOM and anti–zip-bomb), admin-only moderation, and an automatic send-rate cutoff shrug off flooding and resource-exhaustion attacks.
- Engineered in async Rust: Built on Tokio for non-blocking, highly concurrent networking and a fluid ratatui interface — memory-safe, dependency-light, and cross-platform across Linux, macOS, and Windows.
yay fallegji-git
cargo build --release # binary → target/release/fallegji
cargo run # or just run it in project root
cargo test # run tests (can try --release)Note
Fallegji was built with the 2024 nightly Rust toolchain.
Tip
The first build compiles the in-process onion stack (arti), so it takes a while and produces a chunky binary. This cost is compile-time only. Meaning, LAN/idle runtime stays light.
Then, move the fallegji binary from target/release/ to your PATH, whether it be a Linux or Windows machine. This last step enables simply running fallegji from the terminal.
Tip
Avoid a high number of threads n in --test-threads=n. The network tests dislike full parallelism.
demo.mp4
No server or accounts in the conventional sense. Peers talk directly over encrypted TCP, finding each other through a rendezvous address, typically a peer's IP address with a free port of choice.
The peer who creates the chat room is responsible for this rendezvous address and access control. Said peer is known as the admin of the chat room. If an admin's machine can control multiple IP addresses, they can choose whichever rendezvous IP they please.
In the home menu, we can set the interface (LAN, VPN, or Onion) and join an already joined chat. We can also create a new chat or join one. Keep in mind that the names need to be unique per user.
Another important detail is that peers must be mutually reachable. This is trivial on a LAN, but across the internet you need to use a shared VPN (WireGuard, Tailscale, …) so the rendezvous address resolves for everyone. So, for this reason, you need to choose the same interface (VPN) each time you hop on the same chat.
Alternatively, Onion mode needs no shared network at all — each peer reaches the others over onion network, so it works across the open internet with your IP hidden. Pick it in the home menu by pressing Left past the interface list (the "Onion" entry).
The flow for an admin is pretty simple:
- Create a chat → you host the rendezvous; share its address with people you trust.
- Admins run the waitroom (
<C-a>): accept, reject, or kick peers.
A non-admin peer is just a member. They simply need to join the chat by inputting the rendezvous address, chosen by the admin.
Pick Onion in the interface selector. As admin, your rendezvous field auto-fills with a .onion chat link (press c in the waitroom to copy it) — share it with people you trust. Members paste that link to join. The link is a shared rendezvous: any member can host it, so existing members keep chatting and reconnecting even with the admin offline — only accepting new members still needs the admin. Onion chats show a 🧅 by the chat name. The first connect waits a few seconds for onion network to bootstrap ("onioning…" → "onioned").
Lives in ~/.config/fallegji/fallegji.toml (created on first run; %APPDATA% on Windows); chat history sits in ~/.local/share/fallegji/. Global defaults go in the root, per-chat overrides in a [user @ chat] section:
# ── Global defaults (file root) — every key is optional ────────────────────
border_style = "Rounded" # plain | rounded | double | thick
max_height = 5 # max height of the input box, in lines
notifications = true # true | false — popup on each received message
# Colors are [r, g, b], 0–255. Omit any to keep its built-in default.
text_color = [255, 255, 255] # message text
bg_color = [0, 0, 0] # background (omit to keep your terminal's)
border_color = [90, 90, 90] # borders + inactive UI
my_color = [0, 255, 0] # your name
users_color = [0, 255, 255] # other people's names
system_color = [90, 90, 90] # join / kick / system lines
online_color = [0, 255, 0] # the "online" dot
normal_mode = [0, 212, 255] # NORMAL-mode label
insert_mode = [255, 102, 204] # INSERT-mode label
timeout_mode = [255, 49, 49] # TIMEOUT-mode label
# ── Per-chat overrides, keyed "<user> @ <chat>" ────────────────────────────
# Repeat any global key here to override it for just this chat.
["user @ chat-room"]
my_color = [255, 0, 0] # red, only in this room
notifications = false # mute just this chatNote
Identity keys (user_id, user_name, prvkey, rendezvous, and — for onion chats — rendezvous_key) are written per-chat by the app under [user @ chat]. Don't hand-edit them; they're what let you resume a chat and, in onion mode, re-host its shared link.
End-to-end encrypted (X25519 + ChaCha20-Poly1305) with TOFU key-pinning — identity is bound to the public key, so no one can impersonate a known member, and message contents never leave your machine in plaintext. Pitfall: on a bare LAN the discovery metadata (who's joining, their public key) is visible to the local network — run over Onion or a VPN, which encrypt the transport and hide it.
