Download
Two installs · one link
There is no signed installer yet — both apps build from the repository, and that is the next piece of work. A build with no relay URL reaches your Mac on your own network only; going further needs the relay, which you put up yourself.
Host
The machine on your desk
Available
macOS — available
macOS 13 or newer · Intel and Apple silicon
Build the macOS hostScreen, pointer, shells, files and the Mac's audio
Not ready
Windows — not ready
Windows 10 or newer · terminal, screen and input are written
Notify meNot yet built on a real PC · no installer
Client
The phone in your hand
Available
iPhone & iPad — available
iOS and iPadOS 16 or newer
Build the iOS clientSeveral shells at once, search, and every key an iPhone lacks
Not ready
Android — not ready
Not started — there is no Android project in the repository
Notify meNothing to install today
What it does
Six things · all shipping
- [01]
The screen, the files, the sound
Pointer and keyboard on the Mac's display — trackpad, direct touch, joystick and scroll modes, across more than one display. Files in both directions, the Mac's own system audio, and a shared clipboard, all on the same connection.
Routing the Mac's audio to the phone mutes the Mac's own speakers for as long as it runs.
- [02]
A real login shell
Your own login shell on the Mac, not a picture of one. Open several at once and give each one a name.
- [03]
It buzzes you when the run stops
The Mac watches every shell for three things: the terminal bell, the shell exiting, or 45 seconds of quiet after real output. Any one of them pushes a notification to the phone. Start an agent, put the phone away, get told when it stops.
- [04]
The shell outlives the phone
Shells are keyed to your phone's identity key, not to a socket. Background the app, lose the network, force-quit it — the shell keeps running on the Mac. Output from while you were gone is buffered, 256 KiB of it, and replayed the moment you attach again.
- [05]
Every key an iPhone keyboard lacks
Esc, Tab, Ctrl, Alt, Cmd, Shift, the arrows, Home, End, PgUp, PgDn, Del, F1 to F12, and the combinations you type without thinking: ^C ^D ^Z ^L ^R ^A ^E ^K ^U ^W. A modifier stays armed until the next key; double-tap and it locks.
- [06]
Search ten thousand lines of scrollback
Find in the scrollback, with every hit highlighted where it sits. Jump back to the top. Change the text size. The buffer keeps 10,000 lines.
How it works
Four steps
- 01
Install both
The host on the Mac you want to reach, the client on your phone.
- 02
Pair them once
On your own Wi-Fi, or by scanning the code the Mac shows. Either way the Mac asks you to approve the phone, by hand.
- 03
Open a shell from anywhere
A real login shell on the Mac, over a link only your two devices can read. On your own network out of the box; further afield once you have put up the relay.
- 04
Put your phone away
Your agent keeps working on the Mac. When it finishes, or stops to ask you something, the Mac buzzes your phone.
Security
Five claims
This is the part of Remote Coder worth checking, so here is enough to check it. Each claim below names the file it lives in. The whole model is written down in docs/AUTH.md, including what is still weak.
What it is built from
- Password verifierArgon2id · 64 MiB · 3 passes
- Handshake proofHMAC-SHA256, both ways
- Identity keyX25519, pinned on the phone
- Session sealXChaCha20-Poly1305
- Wrong passwords5 per key · 50 total · 15 min
The password is never sent
The Mac holds the access password, and one tap has it generate a fresh one — twelve random symbols, 60 bits. It is kept only as an Argon2id hash, 64 MiB of memory and three passes per guess, and the phone proves it knows the password by answering with an HMAC instead of handing it over.
packages/rc_core/lib/src/auth/auth_proof.dart
Both ends have to prove it
The phone proves it knows the password and the Mac proves it back, under a separate label so neither answer can be replayed as the other. Each proof is bound to both identity keys and to a value derived fresh for that session, so a recorded handshake is useless against another Mac, another phone, or the same pair tomorrow. Proofs are compared in constant time.
packages/rc_core/lib/src/auth/auth_proof.dart
Everything is sealed twice
Each side keeps a long-lived X25519 identity key and mints a throwaway one for every session; both agreements are HKDF-expanded into one key per direction, so a frame cannot be reflected back at the end that sent it. Signaling is sealed with XChaCha20-Poly1305, and the control and terminal payloads carry a second seal on top of WebRTC's own encryption.
packages/rc_core/lib/src/crypto/cipher.dart
A correct password is not enough
The first time an unknown phone reaches the Mac, the Mac stops and asks whoever is sitting at it — device name, key fingerprint, approve or decline, and the request expires on its own. A password can be read off a screen or forwarded, so it never attaches a new phone by itself: you cannot pair one to a Mac you are not standing at.
apps/host/lib/ui/host_pairing_approval.dart
The phone remembers which Mac
On the first connection the phone pins the Mac's identity key and refuses a different one afterwards, behind a full-screen warning whose primary button is Do not connect. Scanning the code the Mac puts up — it carries the key and takes itself down after 90 seconds — removes that first unpinned connection altogether.
apps/client/lib/auth/identity_warning_page.dart
What this does not protect against
Your unlocked phone, or your open Mac
Someone holding your unlocked phone has whatever the phone has, exactly as with any saved credential; someone sitting at your Mac does not need the phone at all. Neither is a thing encryption can answer.
“Direct” is not unconditional
Off your own network the session tries for a direct path between your two devices and falls back to a TURN relay when the network refuses one. The relay carries sealed bytes and cannot read the session — but the path is not always direct, so do not read the word as a guarantee.
The model is not finished
An attacker present for a first, unpinned connection still captures the proof and can attack it offline, and the value stored on the Mac is enough to authenticate with. A PAKE would close both and is not built.
The whole threat model, row by row, is in docs/AUTH.md — including the parts it says are still weak.
One payment, once
Founding lifetime · $59 · not yet on sale
Your screen and your keystrokes go straight between your own two devices, wherever the network allows it — and stay sealed end to end when it doesn’t. Every remote-desktop service that bills monthly is paying to carry your pixels, so the longer you work the more you cost it. Nothing here recurs, so the price doesn’t either.
Founding lifetime
$59
One payment · no subscription
The intended price, held for the first 500 people. Not on sale yet — the apps build from source.
There is nothing to buy here yet. Both apps build from the repository today, and no payment of any kind is taken on this site. This is the price the founding lifetime will be on the day building them stops being the way in — held for the people who ask for it before then.
One line by email · nothing is charged
What the licence covers
- [1]Both apps — host and clientYes
- [2]macOS host · iPhone & iPad clientNow
- [3]Windows · Linux · AndroidWhen they land
- [4]Every future updateYes
What isn’t there yet
- No installerBoth apps build from the repository
- Mac and iPhone onlyWindows is close; Android has not started
- Off your network needs a relayYou put up the Worker and build with its URL
- An account on first launchBoth apps ask you to sign in before the first connection
- v0.1.0, in testVerified on my hardware, not yet on many people's
Tell me where to send it
Say which platform you are waiting for and whether you want the founding price held. You get one message back when there is something to install, and nothing else, ever.








