Skip to content

materia79/nircc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nircc

nircc is a self-hosted IRC client that runs as a small Node.js server and serves a modern web UI to your browser. Because the server holds the IRC connection, you stay present in channels even when your browser is closed, and your full message history is always available the moment you reconnect.

Features

  • Always-on IRC connection — the server maintains the IRC socket; you receive everything even while offline
  • Persistent message history — all channel and private-message history is stored locally in SQLite and loaded on demand
  • Progressive Web App (PWA) — installable on desktop and mobile, works in standalone mode
  • Multiple IRC server profiles — save, edit, and switch between servers from the settings panel
  • TLS support — connect to servers over plain-text or TLS (default port 6697)
  • Real-time updates — the browser UI stays live via WebSocket
  • File uploads — attach files up to 50 MB; links are shared in chat and served directly by nircc
  • Image previews — external images in chat can be proxied and shown inline (SSRF-safe, public IPs only, 8 MB limit)
  • Web Push notifications — receive push notifications for new private messages (queries) on any subscribed device
  • Reconnect with exponential backoff — configurable cap (2 – 256 seconds); reconnects automatically on disconnect
  • Dark and light themes — toggle from the chat action menu; persisted across sessions
  • Resizable sidebar — drag the sidebar edge to your preferred width; remembered per browser
  • Font scalingCtrl + scroll wheel to adjust text size
  • Byte counter — live 0/480 indicator enforces the IRC message byte limit before you send
  • IRC slash commands — full command palette directly in the message input
  • CTCP support — send and receive PING / VERSION / TIME; latency displayed for PING replies
  • User context menu — right-click any nick in the user list for WHOIS, QUERY, Op/Voice/Deop/Devoice, Kick, and CTCP actions

Requirements

  • Node.js 18 or later
  • npm (bundled with Node.js)

Installation

git clone <repo-url> nircc
cd nircc
npm install

Configuration

Copy or create conf.json in the project root. All fields are optional; sensible defaults apply when the file is absent.

{
  "port": 3000,
  "subfolder": "/",
  "push": {
    "vapidPublicKey": "...",
    "vapidPrivateKey": "...",
    "vapidSubject": "mailto:admin@example.com"
  }
}
Key Default Description
port 3000 HTTP port nircc listens on. Overridden by the PORT environment variable.
subfolder "/" Base URL path when nircc is served behind a reverse proxy under a subdirectory (e.g. "/irc/").
push.vapidPublicKey VAPID public key for Web Push. Leave empty to disable push notifications.
push.vapidPrivateKey VAPID private key for Web Push.
push.vapidSubject "mailto:admin@example.com" Contact URI included in VAPID tokens.

Generating VAPID keys

npx web-push generate-vapid-keys

Paste the output into conf.json to enable Web Push notifications.


Running

npm start

nircc starts and prints:

nircc listening on http://localhost:3000

Open that URL in your browser to use the client.

Environment variables

Variable Description
PORT Overrides the port value in conf.json.

Command-line flags

Flag Description
--no-console Disables the interactive server console (useful when running under a process manager).

First-time setup

  1. Open the app in your browser.
  2. Click Connect in the sidebar (or the gear icon) to open Settings.
  3. Under Connection, add an IRC server using the Add button. Fill in the host, port, and whether to use TLS. Common public networks:
    • irc.libera.chat / port 6697 / TLS ✓
    • irc.oftc.net / port 6697 / TLS ✓
    • irc.freenode.net / port 6697 / TLS ✓
  4. Fill in your Nickname, Username, and Real name.
  5. Click Save, then Connect.

Your server profiles and identity settings are persisted on the nircc server and restored across sessions.


Slash commands

Type commands directly into the message input.

Command Description
/join #channel Join a channel
/part [#channel] [reason] Leave a channel (defaults to the active channel)
/leave [#channel] [reason] Alias for /part
/nick <new-nick> Change your nickname
/query <nick> Open a private message conversation
/whois <nick> Look up a user
/topic [#channel] [new topic] View or set a channel topic
/mode <target> [modes] [args] View or set channel/user modes
/kick <#channel> <nick> [reason] Kick a user from a channel
/ctcp <nick> <PING|VERSION|TIME> Send a CTCP request

Settings reference

Settings are organised into three tabs in the Settings panel.

Connection tab

  • IRC server profiles — add, edit, and delete saved servers. Each profile stores the hostname, port, TLS flag, and optional server password.
  • Identity — nickname, username, real name.
  • Client strings — optional VERSION reply string and quit message.

Options tab

  • Connect on Startup — automatically connect when the page loads.
  • Reconnect on disconnection — re-establish the connection if it drops, using exponential backoff.
  • Backoff cap — maximum delay between reconnect attempts (2 – 256 seconds; default 32 s).
  • Notifications — enable or disable Web Push for new private messages globally, and toggle push per device.

Chat tab

  • Indent wrapped chat lines — visually indent lines that wrap past the first line.
  • Show Debug Messages — show raw-level debug output in conversations.
  • Automatic file previews — show a preview widget for files you upload before sending the link.
  • Auto-load image previews — automatically load and display external images inline (when disabled, a "Load preview" button is shown instead).

File uploads

Click the 📎 (paperclip) button, or drag and drop a file onto the message input. nircc uploads the file to its own server (max 50 MB) and inserts the link into your message. Uploaded files are served at /uploads/<token>/<filename>.

Download counts per upload are tracked in real time and broadcast to all connected browser tabs.


Web Push notifications

When VAPID keys are configured in conf.json, the browser can subscribe to push notifications for new private messages (queries). Subscriptions survive browser restarts and work even when the tab is closed.

Push notifications can be toggled:

  • Globally — via Settings → Options → Notifications
  • Per conversation — via the (chat actions) menu or right-clicking the conversation in the sidebar

Running behind a reverse proxy

nircc is designed to sit behind nginx, Caddy, or any other reverse proxy.

Example nginx snippet for serving nircc at /irc/:

location /irc/ {
    proxy_pass http://127.0.0.1:3000/irc/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
}

Set "subfolder": "/irc/" in conf.json to match.


Data storage

Path Contents
data/history.db SQLite database — message history, settings, server profiles, push subscriptions
data/uploads/ Uploaded files
data/nircc-server.log Server log (when enabled)

data/ is git-ignored and will not be committed.


Running as a system service (systemd)

[Unit]
Description=nircc IRC client
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/nircc
ExecStart=/usr/bin/node index.js --no-console
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Save to /etc/systemd/system/nircc.service, then:

sudo systemctl daemon-reload
sudo systemctl enable --now nircc

Keyboard shortcuts

Shortcut Action
Enter Send message
Shift + Enter Insert a newline
Ctrl + Scroll Increase / decrease font size

IRCnet compatibility status

This section tracks how completely nircc implements the IRC protocol as used on IRCnet (RFC 1459 / RFC 2812) and related de-facto standards. It is intended as a working checklist for future development.

Legend: ✅ implemented · ⚠️ partial · ❌ not implemented


Connection and registration

Feature Status Notes
TCP connect (plain)
TLS connect Certificate validation is disabled (rejectUnauthorized: false)
TLS certificate verification Always trusts the server certificate
PASS (server password)
NICK (registration)
USER (registration)
QUIT (with message) Configurable quit message
PING / PONG (keepalive) Auto-handled
Automatic reconnect Exponential backoff, configurable cap
Connect on startup Optional setting
IRCv3 CAP negotiation No CAP LS / CAP REQ / CAP ACK
SASL authentication

Registration numerics

Numeric Name Status Notes
001 RPL_WELCOME Triggers post-connect self-WHOIS
002 RPL_YOURHOST Received but silently ignored
003 RPL_CREATED Received but silently ignored
004 RPL_MYINFO Received but silently ignored
005 RPL_ISUPPORT (FEATURE) Not parsed; supported modes/prefixes are hardcoded
375/372/376 MOTD Not displayed to the user
251–255 LUSERS Not displayed
265/266 Local/global user count Not displayed

Nickname management

Feature Status Notes
NICK (change while connected) Promise-based with 10 s timeout
NICK change reflected in user lists All joined channels updated
433 ERR_NICKNAMEINUSE Error surfaced to UI
432 ERR_ERRONEUSNICKNAME
436 ERR_NICKCOLLISION
437 ERR_UNAVAILRESOURCE
Automatic nick recovery after reconnect Reconnects with original nick; no alt-nick or ghost/regain
MONITOR / WATCH (nick online tracking)
ISON / USERHOST

Channels

Feature Status Notes
JOIN
PART (with reason)
KICK (with reason)
TOPIC (get and set)
PRIVMSG to channel
MODE (send arbitrary modes) Raw mode string forwarded to server
Channel mode display in chat Mode changes shown as status messages
User-list op/voice prefix tracking @ and + tracked via MODE
NAMES list (353/366) Full refresh on join
INVITE (send) No /invite command
INVITE (receive / display) Incoming INVITE not shown
LIST (channel browsing) No /list command or channel browser
JOIN with key (+k channel) /join #channel key not parsed; key not forwarded
Ban list (367/368) MODE +b sent but ban-list numerics not processed
Ban exception list (346/347)
Invite exception list (348/349)
Half-op prefix (%) ⚠️ Prefix preserved from NAMES but +h mode change not tracked
Admin / owner prefixes (~ &) ⚠️ Prefix preserved from NAMES but mode changes not tracked
Multi-prefix (several prefixes per nick) ⚠️ Display-only; relies on server sending combined prefix in NAMES

Messaging

Feature Status Notes
PRIVMSG (send, channel)
PRIVMSG (send, private query)
PRIVMSG (receive, channel)
PRIVMSG (receive, private query)
Outgoing message byte-limit enforcement 480-byte cap with live counter
Long-message truncation ⚠️ Truncated to fit one line; no automatic splitting across multiple PRIVMSGs
NOTICE (receive from server/users) Plain-text NOTICEs are silently discarded; only CTCP-encoded NOTICEs (replies) are handled
NOTICE (send) No /notice command
/me — CTCP ACTION (send)
/me — CTCP ACTION (receive/display) ACTION messages arrive as plain PRIVMSG; \x01ACTION …\x01 envelope is not stripped or styled
mIRC color codes (\x03) Rendered as raw control characters
IRC bold (\x02)
IRC italic (\x1D)
IRC underline (\x1F)
IRC reverse (\x16)
IRC strikethrough (\x1E)
IRC monospace (\x11)
IRC reset (\x0F)

AWAY status

Feature Status Notes
AWAY (set/unset self) No /away command
Away status in WHOIS (301) Shown in WHOIS output
Away notification for other users AWAY messages from other users not tracked
305/306 RPL_UNAWAY / RPL_NOWAWAY Not handled

WHOIS / WHOWAS

Feature Status Notes
WHOIS (send and receive) Full result displayed in active conversation
311 RPL_WHOISUSER
312 RPL_WHOISSERVER
313 RPL_WHOISOPERATOR
317 RPL_WHOISIDLE Idle time and signon time
318 RPL_ENDOFWHOIS
319 RPL_WHOISCHANNELS
301 RPL_AWAY (in WHOIS)
307 RPL_USERIP (registered)
330 RPL_WHOISACCOUNT
671 (secure connection)
378 (actual host)
276 (certificate fingerprint)
401 ERR_NOSUCHNICK
WHO / 352 RPL_WHOREPLY
WHOWAS / 314 RPL_WHOWASUSER

CTCP

Feature Status Notes
CTCP PING (auto-respond to incoming)
CTCP PING (send, with latency display)
CTCP VERSION (auto-respond) Configurable reply string
CTCP VERSION (send)
CTCP TIME (auto-respond)
CTCP TIME (send)
CTCP ACTION (/me) Not sent or specially rendered on receive
CTCP CLIENTINFO
CTCP USERINFO
CTCP FINGER
CTCP SOURCE
DCC SEND / CHAT Out of scope (no direct connection support)

Server operator features

Feature Status Notes
OPER
KILL
WALLOPS / GLOBOPS
REHASH / RESTART / DIE
CONNECT / SQUIT
STATS
LINKS
TRACE

IRCv3 extensions

None of the IRCv3 extensions are currently negotiated via CAP. Implementing CAP LS / CAP REQ is the prerequisite for all items below.

Extension Status Notes
message-tags Tags on incoming lines are not parsed
server-time Timestamps come from the nircc server clock, not the IRC server
echo-message Self-echo is handled by a local guard, not the extension
away-notify
account-notify
extended-join
chghost
batch
labeled-response
multi-prefix
userhost-in-names
MONITOR
sasl
msgid
draft/pre-away

Local client features (no protocol equivalent)

Feature Status Notes
Ignore list No local message filtering
Highlight / mention detection Own nick is not highlighted in incoming messages
Sound / visual mention alerts
Channel auto-join on connect No saved channel list; user must /join manually each session
Conversation search / grep
Log export

Suggested next priorities

Based on the gaps above, these are the most impactful items to tackle first:

  1. NOTICE display — plain-text server and user NOTICEs are completely silent right now; this breaks things like NickServ registration flows and server announcements.
  2. CTCP ACTION (/me) — extremely common; both receive rendering and /me send support.
  3. IRC text formatting — strip or render \x02 bold, \x03 colour, \x1F underline, \x0F reset; required for many networks and bots.
  4. MOTD display — servers send this immediately after connect and it often contains important rules/information.
  5. NOTICE send (/notice) — needed for interacting with services on many networks.
  6. Channel auto-join — save a list of channels to rejoin automatically after connect.
  7. /away command — set/unset away status.
  8. /invite command — invite users to a channel.
  9. IRCv3 CAP negotiation — unlocks server-time, away-notify, account-notify, extended-join, and eventually SASL; foundational for many improvements.
  10. SASL PLAIN / EXTERNAL — needed for modern network authentication (Libera.Chat, OFTC).
  11. Highlight / mention detection — notify when own nick appears in a channel message.
  12. Channel auto-rejoin on reconnect — currently all channels are lost on disconnect.
  13. 005 ISUPPORT parsing — replace hardcoded mode/prefix assumptions with server-advertised values.
  14. TLS certificate verification — currently all certificates are trusted without validation.

License

MIT

About

Self-hosted IRC bouncer-style web client with persistent history, real-time sync, and installable mobile/desktop PWA support.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors