beeper-rs is an independent, unofficial open-source Rust desktop application, HTTP/1.1 REST server, RFC 6455 WebSocket server, and client SDK that implements the public Beeper Desktop API protocol.
beeper-rs never modifies or locks the original Beeper Desktop directory (BeeperTexts or BeeperTexts-<profile>):
beeper-rsstores all database and media files in an isolated directory (~/.config/beeper-rson Linux,~/Library/Application Support/beeper-rson macOS, or%APPDATA%\beeper-rson Windows).beeper-rskeeps its data in its own database file,beeper-rs/beeper-rs.db. The file uses SQLiteSTRICTtables and a schema version (PRAGMA user_version).beeper-rsstops with a clear message if the file has a different schema version.beeper-rsneeds SQLite 3.37 or later.beeper-rsdoes not copy Beeper Desktop data by default. A newbeeper-rsdirectory starts empty and signed out.- On first start, if Beeper Desktop data is available, the setup window asks "Copy from Beeper Desktop" or "Start Fresh". To copy,
beeper-rsreads a temporary snapshot ofindex.dbandaccount.db(with their WAL files). It reads the chats, the participants, the messages, the room keys, the key backup key, and the cross-signing keys. Then you sign in, andbeeper-rsgets its own device. Beeper Desktop keeps its device and its files. After the sign-in,beeper-rssaves the copied data and signs its new device with the copied cross-signing key, so no other verification is necessary. If the import fails, the window shows the error and nothing changes. - Earlier builds used a
BeeperRsdirectory. On start,beeper-rsmovesbeeper-rs.dbandmedia/fromBeeperRstobeeper-rsand deletesBeeperRs, which also removes the old copy of the Beeper Desktop database.
- When no Beeper session is available,
beeper-rsopens the Beeper sign-in window: "Continue with Email", the email screen, the six-digit code screen, "Resend", and "Pick a Username" for new accounts. beeper-rssends the sign-in requests to the Beeper cloud API (https://api.beeper.com) and then signs in to the Matrix homeserver (https://matrix.beeper.com) with the returned JWT. SetBEEPER_API_URLandBEEPER_MATRIX_URLto use different servers.- The Desktop API routes
POST /v1/app/setup/start,/email,/response, and/registeruse the same cloud flow and return the same response shapes as Beeper Desktop. - "Continue with Google" is not available. Use email.
- After sign-in, the "Connect Chat Accounts" window shows the networks and your cloud chat accounts.
beeper-rsreads the cloud accounts from the Beeperwhoamiresponse (user.bridges) at sign-in and at each start. It skips local bridges and self-hosted bridges. To add a new account, use the Beeper mobile app. The account then shows inbeeper-rs. beeper-rsdoes not sync Matrix chats yet. After sign-in, the inbox shows only "Note to self" and the chats copied from Beeper Desktop.- Use
--demoto start with the bundled demo account and demo chats. CentralConfigandBeeperStoreenforce an assertion that aborts if the configured working directory points toBeeperTexts.
- Cargo workspace:
crates/beeper-corecontains the Beeper cloud sign-in client, data models, configuration, SQLite store, search index, and platform helpers.crates/beeper-apicontains the Beeper Desktop API server and client.crates/beeper-uicontains the iced interface, fonts, icons, and network logos. The rootbeeper-rscrate contains the binary and the end-to-end tests. - Native Iced 0.14 GUI: Uses
iced(0.14.0) withwgpu(27.0.1) GPU acceleration andtiny-skiasoftware fallback, adapted from thenavifyarchitecture (https://github.com/pythoncrazy/navify). - Bundled typography, icons, and network logos: Embeds
Inter(Regular,Medium,SemiBold,Bold), an icon font withMaterial Symbolsand aLucidesubset, and CC0Simple Iconsnetwork logos directly in the binary. - Beeper Desktop 4.3 layout: Renders the
68pxaccount rail, the compact Inbox sidebar (190pxdefault, drag-resizable) with pinned chats, the rounded conversation card with a floating chat header, date dividers, link previews, quoted replies, voice notes, files, polls, and reactions, the Beeper composer, the Chat Info panel, and a separate Settings window with the Beeper preference groups. - Native cross-platform support: Runs natively on Linux (Wayland and X11), macOS (AppKit / Metal), and Windows (Win32 / DirectX 12 / Vulkan) with OS-specific directory resolution,
file://URL handling, autostart manifests, and protocol handlers. - Fast compilation and linking:
.cargo/config.tomlsetssccacheas therustcwrapper on all platforms,moldas the linker on Linux, andrust-lldas the linker on Windows MSVC targets. CI uses the same tools and keeps thesccachecache in the GitHub Actions cache. - Rust-native protocols and primitives: Implements HTTP/1.1, RFC 6455 WebSockets, SHA-256, SHA-1, Base64, URL percent-encoding, RFC 3339 timestamps, CLI argument parsing, and 32x32 RGBA system tray icon rendering directly in Rust.
- SQLite WAL and inverted search index: Persists state in
beeper-rs/beeper-rs.dbusing SQLite Write-Ahead Logging (WAL) and indexes chats, messages, and settings in an in-memory inverted index. - System colour scheme: Settings > Appearance > Theme has the Light, Dark, and System choices. System is the default and follows the light or dark mode of the device live (the XDG desktop portal on Linux, the native setting on macOS and Windows).
- System window frame: The windows use the native title bar and border. On a Wayland compositor that has no server-side decorations (for example GNOME), beeper-rs uses XWayland to get the system frame.
Install sccache on all platforms and mold on Linux before you build. For example, on Ubuntu:
sudo apt-get install -y mold pkg-config libxkbcommon-dev libwayland-dev
cargo install --locked sccacheThe app and the tests use ffmpeg and ffprobe to decode audio and video, and to record voice notes. Install them on all platforms.
Spellcheck uses the Hunspell dictionary of your locale (for example hunspell-en-us) from /usr/share/hunspell, /usr/share/myspell or ~/.local/share/hunspell. Without a dictionary, spellcheck is off.
Run the following command to execute the end-to-end test suite (including iced_test::Simulator, iced_test::Emulator, headless Wayland via weston --backend=headless, and headless X11 via Xvfb :99):
cargo test --test e2e -- --nocaptureRun the following command on your host machine to launch the desktop GUI. The GUI starts the local API server on 127.0.0.1:23374 only when Settings > Enable Desktop API is on (default: off). Restart beeper-rs after you change this setting:
cargo run --releaseStart the headless server in one terminal:
cargo run -- serve --demo --host 127.0.0.1 --port 23374In a second terminal, query the server with the CLI or curl:
cargo run -- info --host 127.0.0.1 --port 23374
curl -s http://127.0.0.1:23374/v1/info | jq
curl -s -H "Authorization: Bearer bp_tok_beeper_rs_default_secret" http://127.0.0.1:23374/v1/accounts | jq
curl -s -H "Authorization: Bearer bp_tok_beeper_rs_default_secret" http://127.0.0.1:23374/v1/chats | jq- Create a feature branch from
mainfor each change. - Write commit messages that follow the Conventional Commits specification.
- Keep each commit message to one concise sentence in ASD-STE100 Simplified Technical English.
- Do not include automated tool attribution trailers in commit messages.
- Open a pull request against
mainand verify that all checks pass.
This project is licensed under the MIT License.
See LICENSE and NOTICE for details.
This software project was built using Gemini 4 Argon.
The GIF picker uses the KLIPY API key of Beeper Desktop. The repository stores this key masked, not in plain text, but anyone can get it from the code. The key is the property of its owner, who can revoke it at any time. See section 5 of NOTICE.
beeper-rs is an independent open-source software project.
This project is not affiliated with, endorsed by, sponsored by, approved by, or associated with Beeper Inc., Automattic Inc., Texts.com, or any of their subsidiaries or affiliates.
"Beeper", "Texts", "Automattic", "iMessage", "WhatsApp", "Signal", "Telegram", "Slack", "Discord", "Instagram", "Messenger", "LinkedIn", "Google Messages", "Google Voice", "Matrix", "Bluesky", and all other third-party product names, trademarks, service marks, and trade names referenced in this repository are the property of their respective owners. All references to third-party names, protocols, APIs, and trademarks in this repository are strictly for interoperability and identification purposes (nominative fair use) and do not imply any endorsement, sponsorship, or official status.
This software is provided "AS IS", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non-infringement. In no event shall the authors or copyright holders be liable for any claim, damages, account suspension, data loss, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.