A LAN intercom. Hold a key, and the people you choose hear you.
No internet. No accounts. No server. No configuration. Start it on two machines on the same network and they find each other; hold F8 and talk. Your voice goes straight from your machine to theirs and touches nothing else on the way.
It runs on an air-gapped network. It runs in a workshop, a warehouse, a studio or a site office — anywhere there is a LAN and people who need to reach each other faster than walking.






There was an earlier version built from batch files, PowerShell and ffmpeg. It worked. Nearly every failure in it came from the substrate rather than from the intercom: PowerShell 5.1-only APIs, BOM parsing, CRLF, a script base64-embedded inside a .bat, an installer that swallowed exit codes.
The one that settled it was the firewall. Inbound block rules killed a machine because the network-facing program was powershell.exe — a shared system binary that anything can get muzzled, silently. A dedicated executable has its own firewall identity, its own prompt and its own rule. That is the whole reason this is an application rather than a script.
Hold F8 and whoever is selected hears you. Ctrl+1…9 talks to a specific machine, Ctrl+0 to the room. Nothing is transmitted unless the key is held.
A heartbeat every two seconds means the roster greys somebody out within seven of their machine going quiet. Knowing that nobody is listening is worth more than knowing that somebody might be.
The shortcuts are global. You do not alt-tab, you do not click into a window, you do not find a tab — you hold a key in whatever you were already doing.
mDNS discovery, so there are no addresses to type on a normal network. A machine discovery cannot reach is added by address and named at the same time.
DEVS002 is not Rafi. Name a machine when you add it, then rename, correct or remove it later.
Each machine puts its version on the wire, so the roster names anyone running something different from you — for keeping a rollout straight, using only what the machines on your own network say.
Every one of these is recorded in the repository itself. They are here because a choice explained is worth more than a feature listed.
Opus at 20 ms frames, one frame per UDP datagram, sent to each recipient individually. Broadcast would be one packet instead of many, but some WiFi access points rate-limit or drop broadcast frames — and the failure that produces is one person silently hearing nothing, which is the worst thing an intercom can do. Each remote talker gets its own decoder and its own reorder window, so a missing frame is concealed rather than skipped.
Local playback is muted while you transmit, so the echo path never exists and there is nothing to cancel. Full duplex would have meant acoustic echo cancellation, and that becomes the project rather than a step in it.
The Windows firewall rule is added by an NSIS installer hook, and the MSI has no equivalent here. It produced an install that looked identical to the working one and then walked the user into exactly the failure this application was written to remove. A build that ships and then fails silently is worse than a build that does not exist.
A global shortcut can lose a race to another application, and when it does the key silently does nothing — which is otherwise indistinguishable from the app being broken. Every key is listed in the app, including the ones that did not bind.
Every packet is sealed with ChaCha20-Poly1305, and one that fails to authenticate is dropped without a reply. That makes a mistyped passphrase indistinguishable from a network fault: everything appears to run, the roster is empty, and nothing reports an error. So every machine shows a short room code derived from the key — same code, same room.
It has to carry its own copy of WebKitGTK and GStreamer to run on a machine that has neither, which made it 79 MB against the 4 MB of a .deb that simply depends on what the distribution already ships.
A machine whose only job is to listen has to come up receiving before any window has loaded, so the log is kept outside the webview. It records which microphone and speakers were chosen, what was bound, and who was heard from — then rotates once it passes a megabyte.
GitHub is retiring the Intel macOS runner and the job stopped being scheduled at all — it sat queued indefinitely and held every release open behind it. Apple silicon ships; Intel builds from source.
audio capture, encode, decode, playback. Knows nothing about sockets.
net socket, header, peers. Knows nothing about codecs.
session owns both and wires them together.Three modules, and the dependency direction is the design: neither half knows the other exists.
Every one of these is global — while the app runs it owns Ctrl+0…9 for every program on the machine. That is the price of talking to somebody without leaving what you were doing, and it is why the app’s own actions sit on function keys instead of taking more of that space.
One file, on your machine.
It holds the port, the machines you added and the names you gave them, the order they sit in, your rebound keys, your presets and the room passphrase. No account, no sync, no analytics, and no call to anything outside your own network. Delete it and the app is back to a first start.
Windows also needs CMake, which libopus is compiled with. Linux needs libasound2-dev for ALSA.
bun install
bun run tauri buildEach platform builds only its own artifacts; the release workflow in the repository does all of them at once.
v1.4.010 August 2026
1 downloads of this release. Checksums and release notes are on the releases page.
The macOS builds are unsigned, so Gatekeeper will call the app damaged on first run. It is not — the repository has the one command that clears it, and the reason the Intel build is missing.