Skip to content

Repository files navigation

SideTab icon

SideTab

Use an Android tablet as a second display for macOS over USB or Wi‑Fi.

License macOS 13+ Android 8+ GitHub stars

SideTab running on macOS and Android

Project status

SideTab is under active development. The repository version is 0.11.2; main also contains unreleased fixes and performance work newer than that version.

This fork currently does not publish binaries through GitHub Releases. Build from source when testing this repository so the Mac host and Android client come from the same code revision.

Area Current state
USB display Primary validation path; video, touch, high refresh rates, and S Pen support are implemented
Wireless display Functional, but transport/security and reconnect work remain
Display profile Current fork uses a fixed 1400×876 logical HiDPI profile (2800×1752 physical)
Refresh rate 30 / 60 / 90 / 120 Hz are exposed; 60 Hz is the normal default
macOS macOS 13 Ventura or newer
Android API 26 / Android 8.0 or newer

See docs/PROJECT_STATUS.md for the current production blockers, experiments, and issue map.

Important

Wireless video traffic is not yet end-to-end encrypted. Use wireless mode only on a trusted network until the Protocol V2 / TLS work is complete. USB remains local through the ADB reverse-forwarding path.

About

SideTab brings true second-display functionality to your Android tablet — over USB-C cable for the lowest latency, or wirelessly over WiFi after a one-time QR pair. Something macOS doesn't natively support either way.

While Apple's Sidecar only works with iPads, millions of Android tablets sit unused as potential workstations. SideTab bridges that gap with hardware-accelerated H.265 streaming, sub-16ms pipeline latency on USB, and full touch input — making your tablet feel like a real monitor, not a laggy mirror.

Built entirely open-source, SideTab is designed to be fast, lightweight, and seamlessly integrated.

The repository and product were renamed from Side Screen. Existing macOS and Android identifiers and the sidescreen:// pairing scheme remain stable for compatibility.

For full details, features, and documentation, please visit sidescreen.dev

↑ Back to top


Features

USB-C or Wireless

Two ways to connect, same picture quality. USB-C plugs in the cable for the lowest possible latency — the Mac app sets up adb-reverse forwarding for video on port 54321 and control on 54322. Wireless uses a one-time QR pair; after that, the tablet keeps the encrypted pairing and Reconnect is the recovery action. The QR carries the Mac's preferred local address plus IPv4/IPv6 fallbacks, so a home WLAN that filters one address family can still use the other (5 GHz strongly recommended). Wireless sessions use a bounded 60 FPS profile: up to 40 Mbps average, a 60 Mbps one-second peak ceiling, and freshness-aware backpressure between capture, TCP, decoding, and presentation. The auth token is generated locally and stays on your Mac; reset it any time to revoke access. See the wireless 60 FPS path for the implementation contract and validation boundary.

Virtual Display

Create a true virtual display on your Mac. Drag windows to your tablet like a real monitor — not mirroring, but extending.

Virtual Display in macOS Display Preferences

Ultra-Low Latency

Hardware-accelerated H.265 encoding on Mac and decoding on Android. Async pipeline architecture delivers frames in under 30ms.

Low Latency Streaming with Stats Overlay

Touch Support

Use your tablet's touchscreen to interact with macOS. Touch prediction compensates for network latency, making taps and drags feel natural.

Samsung S Pen contact is handled as a direct drawing stroke rather than a touch scroll gesture. Current Mac/Android builds also forward pen pressure, hover movement, tilt/orientation metadata, and the S Pen secondary button. Pressure is delivered through macOS's tablet-style mouse event fields, so apps that read mouse/tablet pressure can vary brush width; this is not a kernel-level Wacom/Apple tablet driver.

HiDPI (Retina) Support

Enable HiDPI mode to render at 2× resolution internally — text and icons are sharp at any logical resolution, just like a MacBook Retina display. Perfect for users with 2K/4K tablets who want a readable workspace without sacrificing sharpness.

Gaming Mode

Enable Gaming Boost for the bounded ultra-low-latency encoder profile. The host pins this mode to its low-bitrate real-time profile; actual throughput depends on the selected display and device.

Customizable

Configure resolution (up to 4K/8K), frame rate (30–120 FPS; 60 FPS is the current balanced default), bitrate and quality presets from the Mac app. The host applies a bounded encoder ladder rather than treating the UI bitrate as an unrestricted wire rate.

macOS Settings — Display & FPS    macOS Settings — Streaming & Status    Android — Connection Screen

Power-aware Android playback

While SideTab is streaming in the foreground over USB, the Android client requests the panel's 120 Hz mode when the tablet is externally powered — even with Android Battery Saver on — and 60 Hz on battery to reduce display, decoder and thermal load. Wireless streams keep a seamless-only 60 Hz request. When the app is backgrounded, the screen is off, or the session ends, SideTab clears its frame-rate and screen-on requests; an unattended session disconnects after the configured grace period (adb shell settings put system sidescreen_auto_disconnect_secs <N>, default 300), capped at 30 seconds on battery. The Mac host must still be set to 120 FPS for the stream itself to carry 120 frames per second.

Headless / portable Mac

Run a Mac with no display of its own — a Mac Studio or Mini on the go, or a laptop in clamshell — using the tablet as its only screen. Enable Launch at Login and Auto-start streaming, and the Mac boots straight into serving the tablet, with nothing to press on the Mac.

↑ Back to top


Requirements

macOS Host Android Client
OS macOS 13 (Ventura)+ Android 8.0 (API 26)+
Hardware Apple Silicon or Intel H.265 hardware decoder
USB mode USB-C port + adb (Android SDK platform-tools preferred; Homebrew is a fallback) USB-C cable + USB Debugging enabled
Wireless mode Same WiFi network as the tablet (5 GHz recommended) Camera for first pair/re-pair + Google Play Services (for ML Kit barcode)

Installation

This fork does not currently publish installers on GitHub Releases. Build the current source version shown in VERSION using the instructions below. The macOS build script writes each DMG and its source/checksum manifest under dist/SideScreen-<version>/<build-id>/ so builds from different versions stay identifiable. After a successful build, dist/current/ points to the newest build. Use that DMG when installing; the root SideScreen.app is build staging, while the installer manages the single user-facing copy at ~/Applications/SideScreen.app.

For Android, the APK built from the current checkout is always AndroidClient/app/build/outputs/apk/debug/app-debug.apk. Run ./scripts/install_android.sh to rebuild and install that exact output. Files under backups/apk/ are recovery snapshots and should not be selected as installers.

⚠️ macOS Gatekeeper If macOS says the app is "damaged", open Terminal and run:

sudo xattr -cr /Applications/SideScreen.app

Then open the app again. This is needed because the app is not notarized with an Apple Developer certificate.

⚠️ ADB Required The Mac app needs adb to communicate with your Android device. If the app doesn't show "Running" after launch, you likely need to install ADB:

SideTab uses the Android SDK's platform-tools/adb when it is installed, then falls back to Homebrew. This keeps the Mac app, APK installer, and adb reverse tunnel on one toolchain. Set SIDESCREEN_ADB=/absolute/path/to/adb when an alternate SDK must be used.

  1. Install Homebrew (if you don't have it):
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  2. Install ADB:
    brew install --cask android-platform-tools
Build from source (for developers)
git clone https://github.com/tverma101/SideTab.git
cd SideTab

# macOS (universal signed app bundle; also removes stale local app snapshots)
./scripts/build_mac.sh

# Optional: install exactly one user-facing copy under ~/Applications
./scripts/install_mac.sh --launch

# Android debug APK
./scripts/build_android.sh

# Put the current Mac DMG and Android APK in one versioned folder
./scripts/package_current.sh

# Rebuild the current source and install on the connected tablet
./scripts/install_android.sh
# Explicitly install an existing APK without rebuilding
./scripts/install_android.sh --skip-build

# Preserve every local APK and the currently installed APK before installing
./scripts/backup_android_apks.sh

The Mac DMG and its BUILD-MANIFEST.txt are written to dist/SideScreen-<VERSION>/<build-id>/; the newest is also reachable at dist/current/SideScreen-<VERSION>-mac-universal.dmg. Android APKs are generated under AndroidClient/app/build/outputs/apk/. Use the debug app-debug.apk there for this local checkout; the installer script rebuilds it before installing. The raw build output directories are excluded from Git.

After both platform builds, ./scripts/package_current.sh verifies the Mac signature and architectures, checks the APK metadata, then copies the pair into artifacts/SideScreen-<VERSION>/ with source provenance and SHA-256 checksums in MANIFEST.txt. That folder contains the two installers and manifest; it does not include a second loose .app bundle.

The backup helper creates a non-overwriting snapshot under backups/apk/<UTC-timestamp>/. These are local recovery files and are not tracked in Git. Each snapshot includes the available debug and release APK outputs, installed-base.apk when a connected ADB device has Side Screen installed, and MANIFEST.txt with version, signing-certificate, source revision, device, and SHA-256 details. Set SIDESCREEN_ADB_SERIAL when more than one Android device is connected.

If the Mac status says Authorize tablet, ADB can see the USB device but the tablet has not trusted this Mac yet. Unlock the tablet and accept the USB debugging prompt. The USB reverse tunnel and Android connection cannot start until ADB reports the tablet as device rather than unauthorized.

The macOS installer replaces the exact ~/Applications/SideScreen.app target without creating SideScreen.app.previous.* copies. Successful macOS builds, runs, and installs also move any verified stale snapshots left by older installers to the macOS Trash. The Trash is not emptied automatically, and unrelated applications are never searched or changed.


Usage

USB mode (default — lowest latency)

  1. Connect tablet to Mac via USB-C
  2. Launch SideTab on Mac (runs in menu bar — port forwarding is set up automatically)
  3. Open SideTab on tablet → keep on the USB tab → tap Connect
  4. Done — drag windows to your new display

The Android display stays awake while a stream is active and the app is visible. Android can sleep the display when the app is backgrounded; an unattended background session disconnects after five minutes by default. Leave the USB port field blank to use the defaults. A custom video port must be from 1 to 65534, since Android uses the next port for control traffic.

The Mac pauses screen capture after 15 seconds with no connected tablet and resumes it on Connect. When ScreenCaptureKit confirms the desktop has not changed, the Mac skips re-encoding that frame; Android's video and control pings keep quiet sessions alive without sending duplicate frames.

A session that receives nothing from the tablet for five minutes — a Wi-Fi association that dropped without a clean close, a tablet that went to sleep — is timed out by the Mac, which stops streaming and releases the virtual display instead of holding a stale "Connected" state. The deadline is measured from bytes the tablet sends, never from frames the Mac pushes, so a socket that is accepted-but-never-read cannot keep a session alive on its own.

Wireless mode (no cable)

  1. Launch SideTab on Mac → toggle to the Wireless tab → a QR code appears
  2. Open SideTab on tablet → switch to the Wireless tab → tap Scan QR Code → grant camera permission → aim at the QR on the Mac
  3. The tablet remembers the Mac. On subsequent launches, open the Wireless tab and tap Reconnect — no rescan is needed unless the token or Mac address changed.

Wireless mode requires both devices to be on the same WiFi network. 5 GHz is strongly recommended — 2.4 GHz can introduce noticeable jitter on dynamic content. The pairing token authenticates the wireless stream but does not currently provide end-to-end encryption, so use a trusted network. If you need to revoke access, click Reset Token (forget all) on the Mac and re-pair each tablet.

Wireless defaults to the native Android SurfaceView presentation path. VSR/CfL enhancement remains opt-in, so disabling it keeps the tablet on the lowest-overhead hardware decode path.

USB mode remains the lowest-latency option for drawing or fast-paced gaming. Its normal SDR capture uses video-range 420v signaling to match the Android hardware decoder and prevent washed or contrast-shifted colors. Wireless adds 10–50 ms depending on WiFi quality. The old full-range 420f path is retained only as an explicit diagnostic control (defaults write com.sidescreen.app SideScreen_exp_pixelFormat -string 8bit).

The Mac menu-bar menu includes a compact Tablet Brightness slider. It controls the Android panel through the low-latency control channel, remembers the selected level while disconnected, and reapplies it when the tablet reconnects.

Headless mode (no Mac interaction)

In Settings → Startup, turn on Launch at Login and Auto-start streaming on launch, then pick the Startup mode (USB or Wireless). On your next login the server starts automatically — just open SideTab on the tablet and tap Connect (USB) or Reconnect (Wireless).

First-time setup still needs a screen once to grant Screen Recording permission; after that the Mac runs fully headless. For wireless headless use, give the Mac a static IP or DHCP reservation, and consider enabling macOS Screen Sharing as a fallback way in.


Configuration

Setting Options Default
Resolution 720p to 8K, 30+ presets + custom 1920x1200
Frame Rate USB: 30, 60, 90, 120 FPS; Wireless: bounded at 60 FPS 60
Bitrate Host-bounded quality ladder Host preset
Quality Ultra Low, Low, Medium, High Ultra Low
HiDPI (Retina) On/Off Off
Gaming Boost On/Off (bounded low-latency profile) Off
Touch Input On/Off (gates touch and S Pen together) On

Input source (tablet)

Set on the tablet under Settings → Input Source, and applies live without reconnecting:

Mode Finger S Pen
Both Controls Mac Draws on Mac
Touch Controls Mac Ignored
Pen Ignored Draws on Mac
Off Ignored Ignored

The Mac's own Touch Control setting still applies and overrides this, so if nothing responds, check the Mac first. Changing the mode mid-gesture ends the current drag rather than leaving a stuck mouse button on the Mac.


Troubleshooting

"SideTab is damaged" on macOS

This happens because the app is not notarized by Apple. Run this command to fix it:

sudo xattr -cr /Applications/SideScreen.app

Then open the app again.

"Connection refused" on Android

The Mac app sets up adb reverse automatically when streaming starts. If it still fails, run ./scripts/setup-usb.sh from the repo; it prints the selected ADB binary and the full device state (device, unauthorized, or offline). Make sure the tablet is unlocked, using a data-capable USB mode, and has accepted the USB debugging prompt. A charge-only cable will not enumerate as an ADB device.

Android keeps trying to reconnect

Current Android builds only connect after you tap Connect or Reconnect. They do not resume a saved session or retry a dropped connection by themselves. Reinstall the current APK if an older build is still running, then launch the app again.

The connection checklist checks tablet-local prerequisites while idle; it does not open a Mac socket until you explicitly connect.

High latency or stuttering
  • Lower resolution or frame rate
  • Ensure H.265 hardware codec support on your device
  • For USB mode, use a high-quality USB-C cable (not charge-only)
  • For wireless mode, ensure both devices are on 5 GHz WiFi, not 2.4 GHz; reduce refresh rate to 60 Hz if jitter persists
Wireless: "Couldn't reach Mac" / connection times out
  • Both devices must be on the same WiFi network (and same subnet — some mesh routers isolate "guest" devices)
  • Click Start on the Mac before scanning the QR — the listener only binds when the server is running
  • If Android already has a pairing, tap Reconnect first. The repair screen keeps the saved pairing and makes Pair again (scan QR) the secondary action; scan a fresh QR only if the Mac pairing token was reset or discovery cannot recover the Mac
  • The QR includes compatible local IPv4/IPv6 addresses, and Bonjour recovery also returns all usable addresses. This preserves normal WiFi/Internet on the tablet; SideTab does not create a private hotspot
  • If both devices show addresses in the same subnet but Reconnect still times out, test device-to-device TCP reachability; campus or guest WiFi can isolate clients and block both TCP and Bonjour even when the addresses look local. Use a non-isolated SSID or disable client isolation on the access point.
  • macOS may prompt for Local Network permission on first wireless toggle — grant it; without it, LAN inbound is silently dropped
Wireless: "Re-pair required" after restart / reinstall

The Mac's auth token resets when you click Reset Token (forget all) or reinstall the app. Tap Scan QR Code on the Android client and scan the new QR shown on the Mac.

Virtual display not appearing

Grant Screen Recording permission: System Preferences → Privacy & Security → Screen Recording → Enable SideTab


Development

Useful entry points:

MacHost/Sources/                  macOS host
MacHost/Tests/                    Swift tests
AndroidClient/app/src/main/       Android client
AndroidClient/app/src/test/       JVM tests
scripts/                          build, install, benchmark, and maintenance tools
docs/                             architecture, validation, and experiment notes

Before opening a pull request, read CONTRIBUTING.md. Changes to capture, encode, transport, decode, rendering, lifecycle, or input paths should include deterministic tests where possible and real-device evidence when the behavior cannot be proven on hosted CI.

Known work

The issue tracker contains both product blockers and research/measurement tasks. The highest-value unfinished areas are:

  • authenticated, encrypted Protocol V2 for wireless sessions;
  • macOS lock/sleep and Android wake/reconnect lifecycle handling;
  • Android runtime/session ownership cleanup;
  • trustworthy end-to-end latency and smoothness instrumentation;
  • WindowServer / 120 Hz cost attribution;
  • real-device validation of adaptive high-refresh behavior.

A curated map with issue numbers and merge gates lives in docs/PROJECT_STATUS.md.

Contributing

Bug reports should include the exact Mac model/macOS version, Android device/Android version, connection mode, app revision, reproduction steps, and relevant logs. For performance reports, include the configured resolution/refresh rate and whether the symptom is visible stutter, latency, decoder recovery, bandwidth, CPU/GPU load, or connection failure.

See CONTRIBUTING.md for the full workflow.

Privacy and security

See PRIVACY.md for data-handling boundaries. Do not post pairing secrets, signing credentials, private network credentials, or other sensitive material in public issues or logs.

License and attribution

SideTab is available under the MIT License.

This repository is a maintained fork of the Side Screen project originally created by Trần Vương Quốc Đạt. Historical changelog entries and contributor credits are preserved so authorship remains clear. Fork-specific maintenance and development are tracked in this repository.

About

SideTab — use your Android tablet as a second display for macOS over USB-C or Wi-Fi.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages