Open source · written in Go

Stay on IRC.
Forever.

evrd keeps your IRC connections alive while you're away, saves everything you miss, and lets HexChat, irssi, WeeChat and the built-in web client attach and detach whenever you like. All of them share one upstream connection.

Upstream
health

Libera.Chat lag42 ms
OFTC lag88 ms
hackintretry in 24 s
Mentions while away3
Sample data · evrd_upstream_lag_seconds
Live connection map

Your clients come and go. evrd stays connected.

3 attached 1 reconnecting
Clients
evrdnode-a · irc.4evr.sh
Networks
Attached / connected Reconnecting Detached / off
Illustrative sample · one upstream connection per network, shared by every client
What your client sees

Open the laptop.
Everything's still there.

When you attach, you get the welcome burst, your channels with their topics, the backlog with original timestamps, and then live traffic.

  • server-time and echo-message for clients that support them
  • Channel events replayed from *buffextras, so your nick list stays correct
  • Optional: only replay what arrived since you were last attached
HexChat jamesat@Libera.Chat · #evrd
-!- Connecting to irc.4evr.sh:6697 (TLS)…
-!- Logged in as jamesat via server password
-!- Joined #evrd · 38 users · topic restored
Backlog · while you were away · 412 lines
<mira> anyone tried the pebble history backend on a pi?
<tobi> yep, single node, runs fine on arm64
<*buffextras> bob is now known as robert
<robert> jamesat: merged your PR, thanks!
Live
<jamesat> morning — just caught up, nice one
<robert> o/ you never actually left, did you
Replaying backlog… server-time · echo-message
How it works

Every channel stays joined, and every line is saved.

evrd keeps one permanent connection to each network, stays in your channels and counts what's waiting for you. This is the same view as the web app's overview.

Live topology

Networks → channels

Select a network to show only its channels.

Upstream networks
Joined channels
#evrdLibera.Chat · 38 users2 mentions
#go-nutsLibera.Chat · 1,204 users83
#svelteLibera.Chat · 612 users41
#liberaLibera.Chat · 2,731 users12
#debianOFTC · 902 users24
#torOFTC · 455 users7
#cccamphackint · 318 users1 mention
Observable

See what each network is doing.

evrd exports OpenTelemetry metrics (lines per network, lag, disconnects and attached clients) and draws traffic and link history back from VictoriaMetrics. Here's a day where hackint timed out at 03:12 and evrd reconnected on its own.

Message traffic

Lines per hour, last 24h

Libera.Chat OFTC hackint Sample data
evrd_irc_lines_totalevrd_upstream_upevrd_upstream_lag_secondsevrd_upstream_disconnects_totalevrd_irc_clients
Features

A bouncer for everyone from one person to a whole community.

Run a single node with a file on disk, or a cluster behind a load balancer that serves a whole community. Either way, the per-network settings use the names ZNC users already know.

Backlog you can trust

Messages, joins, parts, quits, kicks, nick changes, topics and modes are saved, and replayed to every client with server-time. Channel events come from *buffextras as plain text, so they never confuse your client's nick list. Playback can be limited to what arrived since you were last attached.

Kept per channel (default)2,000 lines

Any IRC client

Attach with a server password user/network:pass. Native clients get the welcome burst, names, topics, backlog and a full-fidelity live feed.

Clients per user (default)unlimited

A real web client

Svelte web app with unread counts, mentions, members, topics and slash commands (/join, /msg, /me, /quote and more), kept in sync with your other clients.

Mentions badge3

ZNC-style *status

/msg *status help to add networks, jump between them, play back a buffer or change settings. ZNC's command names work too.

playback default / max50 / 500 lines

Scales out

Run any number of nodes against the same Postgres and ScyllaDB. If a node dies, its users move to the others in about 20 seconds.

cluster_lease20 s

SSO or passwords

Local passwords, OpenID Connect (Logto or any OIDC provider), or both. Per-client IRC passwords can be revoked one at a time.

session_ttl (default)720 h

Secrets stay secret

Network passwords are encrypted with AES-256-GCM under a key that lives outside the database, and keys can be rotated. Account passwords are bcrypt hashes.

CipherAES-256-GCM

Observable

Exports OpenTelemetry metrics over OTLP, covering lines, lag, disconnects and clients, and draws the dashboard traffic chart from VictoriaMetrics.

otel_interval15 s

Built for hosting others

Roles, per-user limits, suspension, bind hosts and per-user IPv6 addresses. Admins change limits, sign-in, SSO, bind hosts and metrics settings from the web app.

connect_rate (default)5 / s
Muscle memory included

Talk to the bouncer from any client.

Day-to-day network management works from *status too, so a terminal client is enough for everyday use. Coming from ZNC? AddTrustedServerFingerprint and friends still work.

  • Add, connect and remove networks without leaving your client
  • Replay up to 500 lines of any buffer on demand
  • Manage servers, certificate fingerprints, flood and encoding settings
All commands
irssi · *status
/msg *status addnetwork libera irc.libera.chat +6697 jamesat
<*status> Added libera (irc.libera.chat:+6697, nick jamesat). connect libera to bring it online, then jump libera.
/msg *status networks
<*status> * libera           connected    as jamesat        irc.libera.chat:+6697 · 4 channels
<*status>   oftc             connected    as jamesat        irc.oftc.net:+6697 · 2 channels
<*status>   hackint          reconnecting as jamesat        irc.hackint.org:+6697 · 1 channel
<*status> 3 networks. * = this client. jump <network> to switch.
/msg *status jump oftc
<*status> Jumped from libera to oftc.
/msg *status playback #debian 100
<*status> Replayed 100 line(s) of #debian.
evrd.conf · single node
listen     ircs://:6697
api        :8098
db         sqlite:/var/lib/evrd/evrd.db
history    pebble:/var/lib/evrd/history
public_url https://bnc.example.org
irc_host   bnc.example.org
https_listen :443
web_root   /var/lib/evrd/web
tls        acme        # Let's Encrypt, renewed by evrd
secret_key_file /etc/evrd/secret.key
Self-hosted

One config file.
One binary per node.

The config is a few readable directives. Start with SQLite and an embedded Pebble store on one machine, then move to Postgres and ScyllaDB when you outgrow it. evrctl history copy moves your history across.

  • The database backend is picked from the DSN, with no code changes
  • Pure Go, statically built, multi-arch images
  • HTTPS built in, with Let's Encrypt certificates got and renewed automatically, or behind your own proxy
  • A native OpenBSD install: chrooted, unveiled and pledged
  • Upgrades don't take anyone off IRC: an optional connection holder keeps the networks connected while evrd restarts
  • evrctl for admin from a shell

Close the laptop. Miss nothing.

Write a short config, start the containers, create an admin account, add a network. A few minutes from now your nick is online for good.