A group and private chat app for computers on the same local network. One machine hosts, everyone else connects — no internet, no external server, no account.
ConnectX is a self-contained Python chat application built around a simple client-server model: one computer hosts the chat, and any number of other machines on the same network connect to it as clients. It supports both group messaging and private one-to-one conversations, each kept in its own separate thread with unread badges.
Messages can include text and images, and the client raises native macOS notifications for anything received while the app isn't focused. There's no cloud service, no sign-up, and no data ever leaves your local network — every message is relayed directly by the host machine.
One shared conversation everyone sees, plus a fully separate thread for each private conversation — messages never mix between them.
Send JPEG, PNG, GIF, BMP, WebP, and HEIC photos. Images are automatically resized and compressed before sending, so large phone photos stay fast.
Conversations you're not currently viewing show how many messages are waiting, right in the sidebar.
When the app isn't focused, macOS shows who a message is from, whether it's a group or private message, and its content.
One of your own machines is the host. Nothing is stored in the cloud, and nothing leaves your network.
Every message is one JSON object, sent over a plain TCP socket, terminated by a newline — that newline is what tells the receiver where one message ends and the next begins, since TCP itself has no concept of message boundaries. The host reads a message's to field and relays it: "group" goes to everyone, a username goes to just that person.
sequenceDiagram
participant Alice
participant Host
participant Bob
Alice->>Host: {"to": "group", "text": "hi everyone"}
Host->>Bob: relayed to everyone except Alice
Alice->>Host: {"to": "bob", "text": "psst, just you"}
Host->>Bob: relayed only to Bob
On the client, tkinter's event loop and a blocking socket read can't share a thread — so a background thread does nothing but read incoming messages into a queue, and the GUI polls that queue every 100ms. That queue is the only thing that ever touches a tkinter widget from outside the main thread.
Pick one machine on your network to host the chat. This always runs via Python, no matter how everyone else joins:
python3 host.py
It prints its LAN IP address — that's what every client will connect to.
Needs Python 3.9+ and Pillow:
pip3 install pillow
python3 client.py
Optional, for HEIC/HEIF photos: pip3 install pillow-heif
Apple Silicon Mac only. Nothing to install — Python and Pillow are bundled in.
⬇ Download ConnectX.appNot code-signed — first launch, right-click the app → Open to get past macOS's warning. After that it opens normally.
Enter the host's IP and a username, then click Connect.