Inspiration

Standing up to pause a movie, mute a call, or click through Keynote felt dumb in 2026. Every existing "remote" required a cloud account or a server. We wanted zero accounts, zero servers, zero internet.

What it does

Rimote turns an iPhone into a remote for a Mac over Wi-Fi only, no cloud, no analytics.

  • Power: sleep, lock, restart, shut down
  • Audio: volume/mute with live state pushed back
  • Media: play/pause/next/prev, works across YouTube, Spotify, Music
  • Display: brightness up/down
  • Clickpad: arrows + Select, driving Keynote or an AI agent's plan
  • Status bar: Mac name, battery, volume, live

How we built it

SwiftUI on iPhone talks to a Swift/AppKit menu-bar agent over a raw WebSocket on port 8765. Discovery is Bonjour (_rimote._tcp), zero IPs, zero config. Everything is event-driven, not polled, so idle CPU sits near 0%. One frozen contract (PROTOCOL.md) keeps both apps in lockstep. Stack: 89.5% Swift, 10.5% Shell for DMG packaging and notarization.

Challenges we ran into

No cloud meant the agent itself had to be the security boundary. Fix: a hardcoded whitelist, one Swift enum, commands run as executable-plus-args, never sh -c, so no string ever touches a shell. Pairing: a 60-second 4-digit PIN bootstraps a 256-bit token checked in constant time on every message to kill timing attacks. Some things just don't have a fix, brightness is a blind write since macOS won't report the real level back, and enterprise Wi-Fi that blocks Bonjour kills discovery outright.

Accomplishments that we're proud of

Shipped, not prototyped: signed, notarized macOS app, live iOS app on the App Store, v1.0.0 tagged. A 16-check e2e suite drives the real compiled agent binary through the full protocol, pairing, tokens, live push, bad-token rejection, no mocks. Solo project, production-grade security posture.

What we learned

"Local-first" is 10x harder than "cloud-first," Bonjour flakiness and macOS's pmset/osascript quirks ate more time than the actual UI. Freezing the protocol early (PROTOCOL.md) let both apps evolve independently without breaking each other.

What's next for Rimote

Wake-on-LAN for sleeping Macs, without breaking the no-cloud rule. Bigger whitelist (app switching, window management) and better resilience on Bonjour-hostile networks.

Built With

  • claude
  • codex
  • cursor
  • openai
  • swift
Share this project:

Updates