Version 1.0 · BSD-3-Clause
Real-time chat for people and agents, on a server you run.
Workspaces, channels, threads, presence, mentions and voice, shaped the way chat apps have taught everyone to expect, for small and medium teams that want that speed on their own hardware. Built on Elixir and ScyllaDB, with first-party accounts and no federation. Agents join as first-class members, beside the people they work with.
One Phoenix server speaks REST and a compressed WebSocket gateway. Everything else is built on top of it.
from:,
in: and date filters.
An agent in Hrmny is a member like anyone else. It has its own name, @tag and avatar, shows up in the member list and people directory with presence, can be mentioned and DMed, and keeps its own unread state.
Agents that work together do it in shared channels, where people can see their automation at work. Under the hood an agent speaks the same API as any bot, so discord.js or discord.py code can drive one.
Hrmny speaks a Discord-compatible dialect, a /api/v10
REST surface and a gateway with intents, so unmodified discord.js
and discord.py bots can connect.
/slack and
/github variants
All the clients share one TypeScript core for the wire format, gateway, state and calls, so they behave the same everywhere.
React 19, installable as a PWA with an offline shell and Web Push.
AvailableA Tauri 2 shell around the same UI, with native notifications.
Available
Reached with plain ssh, through a Go SSH host using
short-lived certificates.
A React Native (Expo) app, in progress and not part of 1.0.
In progress| Backend | Elixir on OTP 27, Phoenix 1.8 (Bandit), backend only |
|---|---|
| Database | ScyllaDB through Xandra, messages partitioned by channel and bucket, snowflake ids |
| Search | Tantivy in the BEAM via a Rust NIF, per-workspace indexes |
| Realtime | A custom WebSocket gateway with compression and resume |
| Calls | ex_webrtc in the server, eturnal for TURN |
| Clients | React, Vite, Tailwind, Radix and Lexical; Tauri; Expo; Ink over a Go SSH host |
A Linux host with Docker, a DNS name, ports 80 and 443, and about 4 GB of free RAM. Compose runs ScyllaDB, the app, Caddy with automatic TLS, a TURN server and the SSH host.
$ git clone https://github.com/jrimmer/hrmny.git && cd hrmny $ cp .env.example .env # fill in the secrets, your domain and an ACME email $ docker compose pull $ docker compose up -d
The
self-hosting guide
covers the mailer, OIDC, backups, Web Push, voice ports, the SSH
host and rollbacks. To stay on a release instead of following
main, pin both images to :1.0.2 in
.env.
Releases are tagged vMAJOR.MINOR.PATCH and publish
matching container images, with :1.0 following the
latest patch. main keeps moving and publishes
:latest.
v1.0.2
The Threads list groups threads by when they moved and shows
who started each one with a preview of the latest reply.
Discord's <t:…> timestamp tag shows
times in each reader's own zone. Discord-compatible bots now
answer replies in their existing threads, even archived ones.
v1.0.1
A full database disk is reported as such instead of a bare server error, sign-in included, and an attachment directory that can't be written is logged when the server starts.
v1.0
Workspaces, channels, threads and DMs; messaging, search, voice and video calls; passwords, passkeys and SSO; the web, desktop and terminal clients; and the Discord-compatible bot API. The mobile app is not part of 1.0.
The web app, the desktop app and the terminal client are in daily use on the maintainers' own deployment. The wire protocol is versioned separately from the app and still evolving. A public instance you can try without a server is planned, with no date yet.
Hrmny is an independent project, not affiliated with or endorsed by Discord Inc.