soju setup guide: the modern IRC bouncer
Updated June 1, 2026
soju stores your history on the server and hands it to the client on request, using IRCv3 chathistory. Scrolling up in a channel just works, the same way it does in any modern chat app.
That is the difference from ZNC. ZNC dumps a block of missed messages at you when you reconnect. soju lets the client ask for exactly the part of the past it needs.
You need a client that speaks chathistory to feel it: goguma on your phone, gamja in the browser, or Halloy and recent WeeChat on the desktop.
1. Install
soju is packaged in many distributions (apt install soju on recent
Debian/Ubuntu) or built from source with Go. You get two binaries that
matter: soju (the daemon) and sojuctl/sojudb (admin tooling; the name
varies by version — check man soju).
2. Configure
A minimal /etc/soju/config:
listen ircs://0.0.0.0:6697
tls /etc/soju/fullchain.pem /etc/soju/privkey.pem
hostname bouncer.example.com
db sqlite3 /var/lib/soju/soju.db
message-store db
message-store db is the line that turns on persistent history served via
chathistory. Start the daemon (a systemd unit ships with the packages), then
create your user with the admin tool:
sojuctl create-user yourname -admin
3. Add your networks
soju is managed from inside IRC, through its service user BouncerServ.
Connect a client to your bouncer (next section) and:
/msg BouncerServ network create -addr ircs://irc.libera.chat:6697 -name libera -nick yournick
/msg BouncerServ sasl set-plain -network libera youraccount yourpassword
help lists everything; networks, auth and settings are all BouncerServ
commands — no config file editing after day one.
4. Connect clients
Like every bouncer, clients connect to soju, not the network. The username
convention selects the network: yourname/libera (and a client-specific
suffix like yourname/libera@phone lets soju track per-device read state).
Password is your soju password; TLS to port 6697 of your bouncer.
The experience then depends on the client:
- goguma / gamja / Halloy — history, unread markers and multi-network support light up automatically; goguma can even manage networks through the soju extension without BouncerServ commands.
- Traditional clients (Irssi, HexChat) — work fine, but receive
backlog as replay rather than scrollback; enable their
server-timesupport for correct timestamps.
ZNC or soju?
Choose soju if your clients are modern — the chathistory experience is the whole point — or if you want the same stack used by hosted bouncer services. Choose ZNC for its enormous module ecosystem and decades of documentation. Both are small, stable daemons; you can even run both while deciding. Either way, the bouncer overview explains the architecture you have just deployed.