Skip to content

gabrieldonadel/entangle

Repository files navigation

Entangle — your Mac's pointer, in your pocket.

License: MIT macOS iOS Android Stars


Turn your phone into a trackpad for your Mac. Free, open‑source, zero‑setup. Stays on your Wi‑Fi, never leaves the room.


↓ Download · ⚡ Quick start · 🛠 Hack on it ·



✨ Why Entangle?

You're across the room. The Mac is plugged into the TV. The keyboard is buried under cables. Pick up your phone instead.

Feature What you get
🖱 Trackpad mode Smooth, sub‑frame pointer with two‑finger scroll & tap‑to‑click.
⌨️ Keyboard relay Type from your phone. Modifier keys, arrows, the works.
🔒 LAN‑only by default No accounts, no cloud, no telemetry. Pairs over the local network.
📡 Auto‑discovery Bonjour / mDNS finds your Mac the moment the app opens.
🌓 Native everywhere React Native macOS on desktop, Expo on mobile. One repo.

🔌 How it works

Phone → LAN → Mac

The mobile app advertises itself over Bonjour / mDNS. The desktop daemon listens on the LAN, the phone connects, and from then on every gesture is a tiny WebSocket frame on your local network. No relay servers. No internet required. If your router goes down, Entangle keeps working.

The wire format is a single shared TypeScript package — @entangle/protocol — imported by both clients, so the desktop and the phone can never disagree about what a message looks like.


📥 Install

From a release

Platform Download
macOS (Apple Silicon) Entangle.dmg
iOS App Store
Android Google Play · entangle.apk

Build from source

# 1. Clone
git clone https://github.com/gabrieldonadel/entangle.git
cd entangle

# 2. Install dependencies
pnpm install

# 3. CocoaPods for the desktop app (first clone only)
cd apps/desktop/macos && bundle install && bundle exec pod install && cd -

# 4. Run the desktop app
pnpm desktop:start    # in one terminal — Metro on port 8090
pnpm desktop:macos    # in another     — build & launch the macOS app

# 5. Run the mobile app
pnpm mobile:start     # Expo dev server
pnpm mobile:ios       # iOS simulator / device
pnpm mobile:android   # Android emulator / device

That's it. The phone will find the Mac on its own — pick it from the discovered list and start moving the pointer. macOS will ask for Accessibility permission the first time; the desktop UI is gated until you grant it.


🧰 Requirements

Node.js ≥ 18
pnpm 10.x
Xcode 15+ (for iOS & macOS builds)
CocoaPods bundle install && bundle exec pod install inside apps/desktop/macos
Accessibility macOS Accessibility permission — required to synthesize pointer / keyboard input

📦 What's in the box

entangle-monorepo/
├─ apps/
│  ├─ desktop/      ← React Native macOS 0.81 + Expo 55  (the macOS server)
│  ├─ mobile/       ← Expo 55 + Expo Router + RN 0.83    (iOS / Android client)
│  └─ website/      ← Vite + React 18                    (marketing site)
├─ packages/
│  └─ shared/       ← @entangle/protocol — shared wire format (TypeScript)
├─ pnpm-workspace.yaml
└─ pnpm-lock.yaml
App Path Platforms Stack
Desktop apps/desktop macOS React Native macOS 0.81 + Expo 55, React 19.1
Mobile apps/mobile iOS / Android Expo 55 + Expo Router + RN 0.83, React 19.2
Website apps/website Web Vite + React 18

One workspace, one lockfile. Apps and shared packages all live in the same pnpm workspace. The root .npmrc sets node-linker=hoisted so each app gets a flat node_modules tree — conflicting versions (e.g. desktop's react-native@0.83.6 vs mobile's react-native@0.83.4) get nested under the consuming app, while shared deps hoist to the root. Patches for the macOS port of Expo are pinned to specific versions in pnpm-workspace.yaml so they only touch the version desktop resolves to.


🛠 Development

pnpm lint                               # eslint across every workspace
pnpm desktop test                       # jest (desktop unit tests)
pnpm desktop test -- path/to/file.test  # single test file
pnpm desktop <cmd>                      # forward any command into apps/desktop
pnpm mobile <cmd>                       # forward any command into apps/mobile

packages/shared is the source of truth for messages on the wire — touch it once, both clients update. All wire messages carry v: 1; bump PROTOCOL_VERSION for breaking changes and the server will close mismatched clients with code 4001.


🗺 Roadmap

  • Trackpad + scroll + tap‑to‑click
  • Keyboard relay
  • mDNS auto‑discovery
  • Dock enumeration & app activation
  • Media keys & system shortcuts
  • Windows desktop client
  • Apple Watch quick‑actions

See open issues for the live picture.


🤝 Contributing

PRs welcome — small fixes don't need an issue first. For anything bigger, open an issue and let's chat.

  1. Fork & branch (feat/your-thing)
  2. pnpm install at the root — that's it; apps share a single workspace
  3. Commit with Conventional Commits
  4. Open a PR against main

📄 License

MIT © Gabriel Donadel. See LICENSE for details.



Enjoying Entangle? Drop a ⭐.

Made with React Native macOS + Expo · No trackers · No analytics · No nonsense

About

A free and open‑source remote mouse app to control your desktop from your phone

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors