ConnectX

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.

Python tkinter TCP sockets macOS

What it is

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.

Features

Group & private chat

One shared conversation everyone sees, plus a fully separate thread for each private conversation — messages never mix between them.

Image sharing

Send JPEG, PNG, GIF, BMP, WebP, and HEIC photos. Images are automatically resized and compressed before sending, so large phone photos stay fast.

Unread badges

Conversations you're not currently viewing show how many messages are waiting, right in the sidebar.

Native notifications

When the app isn't focused, macOS shows who a message is from, whether it's a group or private message, and its content.

No server, no account

One of your own machines is the host. Nothing is stored in the cloud, and nothing leaves your network.

How it works

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.

Get ConnectX

1

Start the host

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.

2

Everyone joining picks one of these

Run with Python

Needs Python 3.9+ and Pillow:

pip3 install pillow
python3 client.py

Optional, for HEIC/HEIF photos: pip3 install pillow-heif

Download the app

Apple Silicon Mac only. Nothing to install — Python and Pillow are bundled in.

⬇ Download ConnectX.app

Not code-signed — first launch, right-click the app → Open to get past macOS's warning. After that it opens normally.

3

Connect and chat

Enter the host's IP and a username, then click Connect.

Known limitations