A native desktop chat application written in Go. TCP-based server, end-to-end encrypted DMs, peer-to-peer voice channels with noise suppression, and real-time presence — packaged in a lightweight native UI.
- Features
- Architecture
- Download
- Self-Hosting
- Client Setup
- Commands
- Encryption
- Voice System
- Presence System
- Roadmap
- Tech Stack
- License
- Real-time text messaging with persistent rooms
- Voice channels with peer-to-peer audio via WebRTC
- Noise suppression (RNNoise) and voice activity detection
- Speaking indicators — real-time visual feedback for who is talking
- Per-peer volume control with right-click popup slider
- End-to-end encrypted DMs — AES-256-GCM, server never sees plaintext
- Friend system with real-time online/offline status
- Room member list showing all members with live presence indicators (● online / ○ offline)
- Password-protected accounts using Argon2id
- Message history persistence via PostgreSQL
- Custom accent color themes (Red, Blue, Green, Purple)
- GitHub Actions CI builds for Windows, Linux, and macOS
┌─────────────┐ TCP :3000 ┌──────────────────┐
│ Client A │ ──────────────────────▶ │ │
│ (Fyne UI) │ ◀────────────────────── │ Go TCP Server │──── PostgreSQL
└─────────────┘ │ │
└──────────────────┘
┌─────────────┐ TCP :3000 │ WS :3001
│ Client B │ ──────────────────────▶ │
│ (Fyne UI) │ ◀────────────────────── ┌───▼───────────────┐
└─────────────┘ │ Signal Server │
│ (WebSocket/HTTP) │
WebRTC P2P └───────────────────┘
Client A ◀─────────────────────────────────────▶ Client B
Server (cmd/server) — TCP server handling auth, rooms, commands, message dispatch, presence, and friend state. Stores messages and membership in PostgreSQL.
Signal Server — WebSocket server on :3001 used for WebRTC signalling (offer/answer/ICE). Also exposes an HTTP /members endpoint polled by clients to display who is in each voice channel.
Client (cmd/app) — Fyne-based desktop UI. Maintains a single TCP connection to the server and a separate WebSocket connection per voice channel join.
Grab the latest release from Releases.
| Platform | File |
|---|---|
| Windows | DarkWave-windows.zip — extract and run DarkWave.exe |
| Linux | DarkWave-linux — chmod +x and run |
| macOS | DarkWave-mac — chmod +x and run |
On the login screen enter:
- Server address — provided by your host (e.g.
85.130.x.x:3000) - Nickname — your username
- Password — created on first login
- Go 1.21+
- PostgreSQL 14+
createdb darkwave- Create
.envin the project root:DB_URL=postgres://user:password@localhost:5432/darkwave?sslmode=disable APP_PORT=:3000 WS_PORT=:3001
cd cmd/server
go run .Port-forward :3000 (TCP chat) and :3001 (WebSocket signalling) on your router for external access.
Download the release zip from Releases, extract, and run. All native libraries (PortAudio, Opus, RNNoise) are bundled — nothing else to install.
On the login screen provide:
- Server address — e.g.
85.130.x.x:3000 - Nickname — your username
- Password — set on first login, verified with Argon2id on subsequent logins
All commands are typed in the message input box.
| Command | Description |
|---|---|
/nick <name> |
Set nickname and log in (prompts for password) |
/join <room> |
Join or create a room |
/leave |
Leave current room |
/dm <nick> |
Open an encrypted DM session with a friend |
/createvoice <name> |
Create a voice channel in the current room (room creator only) |
/voicechannels |
List voice channels in the current room |
/rooms |
List your rooms |
/friends |
List your friends |
/addfriend <nick> |
Send a friend request |
/friendreqs |
View pending friend requests |
/acceptfriend <nick> |
Accept a friend request |
/declinefriend <nick> |
Decline a friend request |
/online |
Refresh online status of friends |
/help |
Show help |
/quit |
Disconnect |
Messages are encrypted client-side before being sent. The server only ever forwards ciphertext.
Alice types "hey"
→ key = SHA-256("alice:bob") ← nicks sorted alphabetically, both sides derive independently
→ plaintext encrypted with AES-256-GCM (random nonce per message)
→ ciphertext sent to server
→ server forwards ciphertext to Bob
→ Bob derives same key independently
→ AES-256-GCM decrypt → "hey"
The server has no access to the key and cannot read DM content.
Room messages are currently plaintext on the wire (TCP). End-to-end encryption for rooms is on the roadmap.
Voice channels use a hybrid WebRTC + signalling server approach:
- Client connects to the signal server over WebSocket at
ws://<host>:3001 - Signal server brokers WebRTC offer/answer/ICE candidate exchange between peers
- Once ICE completes, audio flows directly peer-to-peer (no server relay for audio data)
- Audio pipeline per peer: PortAudio capture → RNNoise (noise suppression) → Opus encode → WebRTC send
- Receive pipeline: WebRTC receive → Opus decode → RNNoise VAD → PortAudio playback
- VAD (voice activity detection) drives the speaking indicators in the UI
- Per-peer volume is adjustable via right-click on a member in the voice panel
Audio device preferences (input/output) are saved per-user via fyne.Preferences.
The member panel shows all users who have access to a room, not just those currently in it.
- On room join the server queries
room_membersfor all DB members and sends** members: ... - It then sends
** online: ...listing those currently connected to the server - When any user connects or disconnects, the server pushes
** presence: <nick> online/offlineto every client currently sitting in a room that user has access to ** joined: <nick>/** left: <nick>events track movement between rooms in real time
This means ● / ○ reflects server-wide connectivity, not just presence in the current room — matching the behaviour of Discord's member sidebar.
- TCP chat server with multiple rooms
- Password-protected accounts (Argon2id)
- Friend system with real-time online/offline status
- Persistent room membership (PostgreSQL)
- Message history persistence
- Room member list with live presence indicators
- Native desktop UI (Fyne)
- Encrypted DMs (AES-256-GCM)
- Custom accent color theming
- Voice channels (WebRTC peer-to-peer)
- Noise suppression (RNNoise) + VAD
- Speaking indicators
- Per-peer volume control
- Audio device selection
- GitHub Actions CI (Windows, Linux, macOS)
- End-to-end encryption for rooms
- Screen sharing (1080p60, hardware encoding)
- Message reactions
- File transfers
| Component | Technology |
|---|---|
| Language | Go |
| UI framework | Fyne |
| Voice transport | Pion WebRTC |
| Audio I/O | PortAudio |
| Audio codec | Opus |
| Noise suppression | RNNoise |
| Database | PostgreSQL + pgx |
| Password hashing | Argon2id |
| DM encryption | AES-256-GCM |
| WebSocket signalling | gorilla/websocket |
MIT
