Build from source
A Cargo workspace of five crates. No custom build system.
Prerequisites
- Rust, current stable, through rustup.
protocon thePATH. Signal’s libraries compile protobufs while building. macOS:brew install protobuf. Debian and Ubuntu:apt install protobuf-compiler.- macOS: the Command Line Tools are enough. The window builds with runtime shaders, so Xcode’s Metal compiler is not needed.
- Linux: the system libraries CI installs.
sudo apt-get install build-essential pkg-config libssl-dev libasound2-dev libgtk-3-dev \
libwebkit2gtk-4.1-dev libsoup-3.0-dev libvulkan-dev libwayland-dev libxkbcommon-dev libxkbcommon-x11-dev \
libx11-dev libxcb1-dev libfontconfig1-dev protobuf-compiler- Windows:
protocon thePATH, and WebView2 for the sign-in window.
Build and run
git clone https://github.com/itz4blitz/tinyclient
cd tinyclient
cargo test --workspace # every crate; no GPU stack is built
cargo build -p chatd -p mediad -p login # the daemon and its helpers
cargo run -p tinyclient --features gui # the window; starts chatd beside it
cargo run -p tinyclient # status and inbox as textThe window is behind the gui feature so that the daemons and the tests never build a GPU stack. tinyclient starts the chatd that sits beside it in target/<profile>, so build both. TINYCLIENT_CHATD names a different one.
The crates
| Crate | Binary | Role |
|---|---|---|
chatd | chatd | The daemon: network adapters, SQLite store, media cache, call signalling. |
tinyclient | tinyclient | The window (GPUI, feature gui) or the text output. |
mediad | mediad | One call: voice gateway, UDP, Opus, Discord’s end-to-end encryption, audio devices. |
login | tinyclient-login | One sign-in window for Discord, Slack and Teams. |
protocol | library | The frames the programs exchange. Local IPC only. |
Release builds
cargo build --release -p tinyclient --features tinyclient/gui -p chatd -p mediad -p login
packaging/bundle.sh # macOS: builds and assembles target/release/tinyclient.app
packaging/dmg.sh dist/tinyclient.dmg # macOS: the app in a disk image
eval "$(packaging/linux/tools.sh)" && packaging/linux.sh # Linux: .deb, .rpm, AppImage and .tar.gz in dist/
packaging\windows.ps1 # Windows: the installer (needs Inno Setup 6) and .zip in dist\On macOS, calls need the bundle: the system grants the microphone to an app, and a bare program run from a terminal borrows the terminal’s permission instead.
Telegram needs your own app id
Telegram asks every client to register an app id, and the id is not in the repository. Register one at my.telegram.org (the app name must not contain “Telegram”) and build chatd with both values in the environment:
TINYCLIENT_TELEGRAM_API_ID=... TINYCLIENT_TELEGRAM_API_HASH=... cargo build -p chatdWithout them, Telegram is listed as unavailable and says why. A binary built this way carries your id, and Telegram holds the id’s owner responsible for what the app does: give it to other people only if you accept that.
Signal, and the AGPL
The signal feature of chatd is on by default. It links presage, libsignal-service-rs and Signal’s libsignal, which are AGPL-3.0, so a chatd built with it is a combined work under the AGPL-3.0. The release binaries are built with it. To leave Signal out:
cargo build -p chatd --no-default-featuresTry it without an account
TINYCLIENT_DIR moves the socket, database and logs to a directory you choose and turns sign-in off, so nothing touches your credential store. --seed-demo fills that directory with invented servers, workspaces, people and conversations for Discord, two Slack workspaces, Telegram, Teams and Signal. #showcase holds every kind of message.
TINYCLIENT_DIR=/tmp/tinyclient-demo cargo run -p chatd -- --seed-demo
TINYCLIENT_DIR=/tmp/tinyclient-demo cargo run -p tinyclient --features gui--seed-demo=livekeeps one conversation busy: someone types, a message lands, a reaction, an edit.- Other variants, comma separated:
expired,many(50 Discord servers),attention,reconnecting. chatdrefuses--seed-demowithoutTINYCLIENT_DIR, so it cannot write into your real store.
Screenshots without screen recording
The gui-shot feature adds --shot out.png, which renders the window to a file and quits. A shell built with it never marks anything read on a network.
TINYCLIENT_DIR=/tmp/tinyclient-demo cargo run -p tinyclient --features gui-shot -- --shot out.pngTests
The chatd tests drive the daemon through its socket against local fakes of each network: HTTP and websocket fakes for Discord, Slack and Teams, and scripted wires for Telegram and Signal. mediad’s tests run a whole encrypted call against a fake voice server. None of them needs an account or the network.