iMessage on Linux, macOS and Windows. A native Rust client on NativeDesktop (AppKit on macOS, GPUI on Linux and Windows) that talks to a BlueBubbles server running on your Mac.
Linux / macOS / Windows Mac
┌──────────────────┐ http + socket.io ┌──────────────────────────────┐
│ Messages (Rust) │ ─────────────────▶ │ BlueBubbles server │
│ NativeDesktop │ ◀───────────────── │ reads chat.db, drives │
└──────────────────┘ │ Messages.app (Private API) │
└──────────────────────────────┘
Threads update live, sends are optimistic and queue while offline, and the window opens on the last known state before the server answers. It idles at 0% CPU.
![]() |
![]() |
On Linux with the Adwaita look, and on Windows:
![]() |
![]() |
scripts/shots macos|linux|windows|all regenerates these from the demo data.
| SIP on | Private API (SIP off) | |
|---|---|---|
| Read and send text, photos, files, audio, stickers, link previews | yes | yes |
Search with from:, has:, before:, after:, in: |
yes | yes |
| Scheduled sends, notifications, Markdown export | yes | yes |
| Pin, mute, draft sync between clients | yes | yes |
| Tapbacks | receive | yes |
| Typing indicators, read receipts, replies, unsend, effects | no | yes |
| Rename groups, add and remove people | no | yes |
Optional extras: Find My locations on contact cards (needs the Mac agent), GIF search through Klipy, and summarize/translate/transcribe through a CanaryLLM gateway.
Not working: FaceTime (upstream helper#38, server#776), sending custom emoji tapbacks, and editing on macOS 26 (hidden until the helper is fixed).
nix run github:FormalStudio/messages
Home Manager:
{
inputs.messages = {
url = "github:FormalStudio/messages";
inputs.nixpkgs.follows = "nixpkgs";
};
# in your home-manager configuration
imports = [ inputs.messages.homeModules.default ];
programs.messages = {
enable = true;
autostart = true; # start with the graphical session
environmentFile = "/run/agenix/messages.env"; # optional, server password etc.
settings.notifications = true; # typed, written to config.toml
theme = { primary = "#6099c0"; }; # optional, writes theme.json
};
}This installs the app, its desktop entry and icon. overlays.default adds
pkgs.messages.
Needs Rust 1.89+, Vulkan, and libxkbcommon, wayland, vulkan-loader,
fontconfig, freetype, alsa-lib. ffmpeg is optional (video posters,
playback).
git clone https://github.com/FormalStudio/messages
cd messages
./scripts/install-linux.sh
This installs ~/.local/bin/messages and a desktop entry.
Install rustup and the Visual Studio C++ build tools, then build with the msvc toolchain and install it with a Start menu shortcut:
cargo +1.95.0-x86_64-pc-windows-msvc build --release -p messages
powershell -ExecutionPolicy Bypass -File packaging\windows\install.ps1- Install the BlueBubbles server and give it Full Disk Access.
- Turn off "Encrypt communications". Reach the Mac over Tailscale or a VPN.
- For the Private API column: disable SIP and turn on Private API in BlueBubbles.
On first launch, paste the server address and password. MESSAGES_DEMO=1 messages runs on fixtures with no Mac.
Settings live in config.toml (~/.config/messages/ on Linux,
~/Library/Application Support/messages/ on macOS), editable from the settings window
(Cmd+,), from Nix as programs.messages.settings, or per key as MESSAGES_<KEY>
(MESSAGES_SERVER_URL, MESSAGES_DEMO=1):
server_url = "http://your-mac:1234"
agent_url = "http://your-mac:1236"
notifications = true
tray = trueSecrets stay in ~/.config/messages/config.json, which the app writes itself (and which
also holds per-chat pins and mutes):
{
"agent": { "url": "http://your-mac:1236", "token": "..." },
"klipy": { "apiKey": "..." },
"canaryllm": { "apiKey": "...", "model": "gemini/gemini-2.5-flash-lite", "language": "Spanish" }
}Environment overrides for the secrets: MESSAGES_SERVER_PASSWORD,
MESSAGES_AGENT_TOKEN, MESSAGES_KLIPY_KEY, MESSAGES_CANARYLLM_KEY.
The first launch after the GPUI build (app id es.canarycoders.messages) moves the server,
agent and notification settings out of config.json into config.toml; caches stay where
they were. The app id is now dev.formalsnake.messages.
On Linux, ~/.config/messages/theme.json is a matugen palette in NativeDesktop's format
(Material roles such as primary and surface, per scheme), reloaded live.
apps/mac-agent runs on the Mac and adds Find My locations, Apple Maps
snapshots, and pins, mutes and GIF favorites synced across clients.
apps/mac-agent/scripts/install-mac-agent.shinstalls it as a launchd agent (port 1236, token in~/.config/messages/agent.json).- For Find My: boot with SIP off and
sudo nvram boot-args="amfi_get_out_of_my_way=1", then runscripts/findmy-keys-mac.shonce to extract the keys. - Add
agentto the client config as above.
Ctrl+N |
new message |
Ctrl+F |
search |
Ctrl+K |
jump to a conversation |
Ctrl+I |
conversation details |
Ctrl+[ / Ctrl+] |
previous / next conversation |
Ctrl+1 to Ctrl+6 |
tapback the last message |
Shift+Ctrl+U |
mark unread |
Cmd on macOS. The clock beside the composer schedules a message.
MESSAGES_DEMO=1 cargo run --release -p messages # fixtures
cargo test --workspace
nix build .#messages # Linux package
bun run agent # the Mac agent
crates/core is the store, transport and BlueBubbles client with no UI
dependencies. crates/desktop is the window on NativeDesktop, checked out beside this repo
(../nativedesktop). CLAUDE.md has the architecture notes, docs/nd-parity.md what the
port keeps of the GPUI build.
MIT. The Noto Sans faces in packaging/fonts are under the
OFL.





