Build from source

A Cargo workspace of five crates. No custom build system.

Prerequisites

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

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 text

The 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

CrateBinaryRole
chatdchatdThe daemon: network adapters, SQLite store, media cache, call signalling.
tinyclienttinyclientThe window (GPUI, feature gui) or the text output.
mediadmediadOne call: voice gateway, UDP, Opus, Discord’s end-to-end encryption, audio devices.
logintinyclient-loginOne sign-in window for Discord, Slack and Teams.
protocollibraryThe 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 chatd

Without 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-features

Try 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

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.png

Tests

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.

Edit this page on GitHub