I got tired of my team's messages living on someone else's server.
Not because I'm paranoid. Just because I could do better. Slack logs everything. Discord has its own rules. Matrix is powerful but setting it up feels like a weekend project. Mattermost is great — if you have an afternoon and enjoy reading YAML.
So I built something simpler.
What is XtermChat?
XtermChat is a self-hosted chat system that runs entirely in the terminal. You deploy the server on your own VPS, your team connects with a CLI client, and that's it. No accounts, no dashboards, no third-party anything.
┌──────────────────────────────────────────────────────────────┐
│ X T E R M C H A T │
│ For Those Who Speak Terminal. │
└──────────────────────────────────────────────────────────────┘
▸ COMMANDS
connect Connect client to a server
disconnect Remove saved server config
status Check server connection
list:rooms List all available rooms
create:room Create a new room
delete:room Delete a room permanently
start:chat Open interactive chat
start:web Open web interface
Why another chat tool?
Fair question. Here's my honest comparison:
| XtermChat | Matrix | Mattermost | Slack | |
|---|---|---|---|---|
| Self-hosted | ✅ | ✅ | ✅ | ❌ |
| Open source | ✅ | ✅ | ⚠️ partial | ❌ |
| Setup time | ~5 min | ~2 hrs | ~30 min | instant |
| RAM usage | ~30 MB | ~1–2 GB | ~300 MB | — |
| Terminal-first | ✅ | ❌ | ❌ | ❌ |
| Your data | ✅ | ✅ | ✅ | ❌ |
The gap I wanted to fill: something that's self-hosted, lightweight, and actually fast to set up — especially for developers who live in the terminal anyway.
The setup is genuinely fast
Server side (your VPS)
git clone https://github.com/dnysaz/xtc-server.git
cd xtc-server
pip install flask flask-cors
sudo ufw allow 8080
python3 server.py start
# [*] Server started in background (PID: 12345)
That's it. No database configuration. No config files to edit. SQLite handles everything automatically on first run.
Client side (your machine)
git clone https://github.com/dnysaz/xtc-client.git
cd xtc-client
make install
xtc connect @your-server-ip:8080
Now you're connected. Create a room and start chatting:
xtc create:room @general
xtc start:chat @general
Total time from zero to chatting: under 10 minutes, including the time it takes to spin up a VPS.
The chat UI
When you run xtc start:chat, you get a full terminal UI — not just a scrolling log. There's a left sidebar showing your identity and connection info, a right sidebar with room details, and a chat area in the middle.
A few things I'm particularly happy with:
Tab to switch modes. Press Tab to move focus from the input box into the chat history. From there you can scroll, select text, and copy it — just like a normal text editor.
Links are clickable. URLs in messages show up with underline formatting. Move your cursor to a link and press Ctrl+L to open it in your browser.
Emoji shortcuts. Type :fire and it converts to 🔥 when you send. Type :e to see all available shortcuts in a floating panel.
XtermChat-CLI | NODE: mac-dana | 103.45.67.89 | [ INPUT ]
┌─────────────┬──────────────────────────────────┬─────────────┐
│ ID │ │ CHANNEL │
│ KETUT │ now You ❯ hey everyone! │ #GENERAL │
│ │ 2m John ❯ hello! │ │
│ GATEWAY │ 5m You ❯ https://github.com│ CREATOR │
│ 103.45.7 │ │ KETUT │
└─────────────┴──────────────────────────────────┴─────────────┘
✏️ INPUT MODE │ ENTER: SEND │ TAB: → CHAT │ Ctrl+X: EXIT
Message ❯❯❯ _
How identity works
There's no signup. Your username comes from your system user (whoami), and your identity is tied to your machine's hardware UUID. First time you send a message, you're automatically registered on the server. If someone else tries to use the same username from a different machine, the server rejects it.
This means:
- No passwords to remember for your identity
- No accounts to create
- Your identity is device-bound — which is actually the right behavior for a team tool
Room passwords are hashed with bcrypt. Only the room creator (verified by hardware PIN) can delete a room or wipe its message history.
Web interface included
Not everyone on a team lives in the terminal. So there's also a web UI:
xtc start:web
# URL: http://localhost:5000
Open it in a browser, enter your server IP, a username, and a 5-digit PIN — that's your identity for the web client. It talks to the same server API as the CLI, so everyone sees the same messages regardless of which client they're using.
The stack
- Backend: Python + Flask, SQLite3
-
CLI: Python with
prompt_toolkit - Web: Flask serving plain HTML + vanilla JS
- Auth: Hardware UUID (CLI) or user-chosen PIN (web)
- Protocol: REST API over HTTP or HTTPS
No Docker required. No Postgres. No Redis. No node_modules. The entire server runs on Python with two pip packages.
What's next
A few things I'm thinking about:
- End-to-end encryption for messages
- File sharing (small files, inline in chat)
- Webhook support for notifications from CI/CD pipelines
- Federation — connecting multiple servers so teams on different VPS instances can chat
But honestly the current version already does exactly what I need day to day. Sometimes simple is the right call.
Try it
- Server: github.com/dnysaz/xtc-server
- Client: github.com/dnysaz/xtc-client
This is the documentation : https://xtermchat.vercel.app/
If you're running a small team, managing a homelab, or just want your chat data to stay on your own infrastructure — give it a shot. The setup is fast enough that there's really no reason not to try.
And if you find something broken or have a feature idea, issues and pull requests are very welcome.
Built with Python. Runs on a $5 VPS. Your data stays yours.
Top comments (0)