Skip to content

Repository files navigation

TetherShot logo

TetherShot

Screenshot your iPhone from a compact Mac app or the menu bar.

USB or Wi-Fi · pixel-perfect captures · saved to a folder you choose · copied to your clipboard.

macOS 14+Swift 6SwiftUIiPhone USB + Wi-FiHomebrew Casknpm versionGitHub starsMIT LicenseVote on Product Hunt

Website · Homebrew · npm · Install · Docs · Support

brew install --cask aopv/tap/tethershot


TetherShot capture beam preview

Status — shipping. USB + Wi-Fi capture, clipboard, global hotkey, per-device folders, Homebrew and npm installs, and in-app self-update are all working. Built and tested on macOS 26 (Tahoe) with iOS 26.

Why TetherShot

macOS already lets QuickTime/OBS mirror a tethered iPhone's screen (it appears as an AVCaptureDevice of media type .muxed). TetherShot wraps that into a one-click menu-bar capture that writes straight to disk and your clipboard — and adds cable-free Wi-Fi capture through Apple's developer-services tunnel. It's the iPhone screenshot tool Apple never shipped.

Features

  • 🔌 USB capture — a trusted, cabled iPhone is grabbed at full resolution via native AVFoundation. Instant, zero setup.
  • 📶 Wi-Fi capture — cable-free over your local network via a RemoteXPC tunnel (pymobiledevice3). Pixel-perfect, even when the phone is locked.
  • 📋 Clipboard — every capture is copied, ready to paste (toggle on by default).
  • ⌨️ Global hotkey — press ⌘⇧7 anywhere to capture every connected device, or choose one preferred iPhone and remember it across launches.
  • 🗂️ Your folder, your rules — any destination, timestamped filenames, optional per-device subfolders.
  • ⬆️ Self-updating — in-app Check for Updates downloads the signed, notarized GitHub release, verifies it, replaces the current app in place, and relaunches.
  • 🪟 Compact Mac app — open it from Applications or Spotlight; closing the window keeps capture running and removes the Dock icon.
  • 🍥 Optional menu-bar control — enabled by default for quick capture and settings, and can be hidden persistently.
  • 🚀 Launch at login — keeps capture and the global hotkey ready in the background.
  • 🔒 Local-first — no account, no analytics, no servers. Screenshots never leave your Mac.

Requirements

  • macOS 14 (Sonoma)+ — developed/tested on macOS 26 (Tahoe)
  • Xcode Command Line Tools — only needed to build from source (xcode-select --install)
  • Node.js 18+ — only needed for npm installation
  • An iPhone you can set to Trust This Computer
  • For Wi-Fi: iPhone + Mac on the same network, plus pymobiledevice3

Installation

Via Homebrew — recommended

brew install --cask aopv/tap/tethershot

Homebrew downloads the checksum-verified, signed, and notarized universal DMG and installs TetherShot into /Applications. Future Cask versions follow the latest stable GitHub Release.

Via DMG

Download the signed, notarized universal DMG from the latest GitHub release, open it, and drag TetherShot into Applications. The same build runs natively on Apple silicon and Intel Macs and becomes the canonical /Applications copy.

Via npm

npm install -g tethershot # installs the CLI (and builds the app)
tethershot install # ensure the app is built into ~/Applications
tethershot # launch it

This path builds from source on your machine and lands in ~/Applications (no sudo). If a signed /Applications/TetherShot.app already exists, the CLI preserves it instead of replacing its Developer ID signature with a local build.

All installation methods use the same bundle identity and settings. Homebrew and the DMG install the canonical /Applications copy. If you install either after using npm, the stale ~/Applications copy is moved to Trash on launch. Future in-app updates replace that canonical copy in place.

npm 11+ blocks postinstall scripts by default, so if the app isn't built after npm install, the explicit tethershot install step always does it.

From source

git clone https://github.com/aopv/TetherShot.git
cd TetherShot
./build.sh # compiles + packages TetherShot.app
open .build/TetherShot.app # launches the app and menu-bar control

On first USB capture, macOS asks for Camera permission — expected: the iPhone screen is delivered through the AVFoundation (camera) privacy bucket. TetherShot never uses your Mac's camera.

Usage

Open TetherShot from Applications or Spotlight, or click its menu-bar icon, then pick your phone. The PNG saves to your folder (default ~/Pictures/TetherShot) and copies to your clipboard. Closing the window leaves capture and the global hotkey active in the background; open TetherShot again to bring the window back.

OptionWhat it does
⌘⇧7Quick-capture the saved preferred iPhone, or every connected device by default
Quick Capture DeviceChoose one iPhone for the hotkey; the selection persists across launches
Copy to ClipboardAlso place each capture on the clipboard (default on)
Organize by DeviceSave into a per-device subfolder
Choose Folder…Pick any destination; remembered across launches
Show in Menu BarKeep quick controls in the menu bar (default on)
Launch at LoginKeep TetherShot available across reboots
Check for UpdatesVerify the latest signed GitHub DMG, replace the current app, and relaunch

Wireless (Wi-Fi) setup — one time

Wi-Fi capture uses a root LaunchDaemon (tunneld) that keeps a RemoteXPC tunnel alive so captures need no sudo.

pip3 install -U pymobiledevice3 # the engine
tethershot setup-wifi # installs the tunnel daemon (admin password once)

Then, with the iPhone connected by USB once:

  • Enable Developer Mode — Settings ▸ Privacy & Security ▸ Developer Mode
  • Enable Wi-Fi reachability — pymobiledevice3 lockdown wifi-connections --state on

After that you can unplug. While the iPhone and Mac share a Wi-Fi network, the menu shows it as (Wi-Fi) and tunneld discovers it automatically. Remove the daemon with bash scripts/uninstall-tunneld.sh.

Why not AirPlay mirroring? On macOS Tahoe, a mirrored iPhone window blacks out whenever a capture context is active — so TetherShot uses the developer-services path instead, capturing the device's own framebuffer regardless of transport.

CLI

tethershot # launch the app
tethershot install # build & install to ~/Applications
tethershot update # update to the latest published version
tethershot setup-wifi # install the Wi-Fi tunnel service
tethershot uninstall # remove the app
tethershot version # print the installed version

How it works

ComponentRole
USBCaptureFlips the CoreMediaIO screen-capture flag, finds the iPhone as a .muxed device, grabs one frame → PNG
WirelessCaptureTalks to the tunneld HTTP API, runs pymobiledevice3 developer dvt screenshot over the Wi-Fi tunnel
UpdaterChecks GitHub Releases, verifies the asset digest and Developer ID signature, then atomically replaces and relaunches the current app
AppModelMain-actor state: device list, destination folder, options, status
MainWindow / MenuContentCompact SwiftUI app window plus optional MenuBarExtra controls
TetherShotAppWindow lifecycle: closing hides the Dock presence while background capture stays alive

Capture backends sit behind a CaptureBackend protocol, so USB and Wi-Fi share one code path. The marketing/docs site lives in /web and deploys to tethershot.apoorvdarshan.com.

Contributing

Contributions are welcome — see CONTRIBUTING.md for how to build, the project layout, and the PR flow.

Security

Found a vulnerability? Please report it privately — see SECURITY.md.

Support

If TetherShot is useful to you:

Star History

TetherShot GitHub star history

License

MIT © 2026 Apoorv Darshan

Not affiliated with Apple Inc. iPhone, macOS, and Apple are trademarks of Apple Inc.

About

macOS menu-bar app that screenshots your iPhone over USB or Wi-Fi — straight into a folder you choose and onto your clipboard. Native Swift + AVFoundation. Install via npm.

Topics

Resources

Contributing

Security policy

Stars

7 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages