The project's README from github.com/0xCodez/DuoDesk. As one markdown file: README.md.
All your computers and your phone, working as one desk.
Screens, apps, files, clipboard, cameras, calls, texts, notifications, mouse and keyboard, shared between Mac, Windows, Linux and Android.
Free and open source. No account, no cloud, no shared network needed.
⬇️ Download 2.5 · Website · Source · What's new · Get started · How it works
Your devices are good at their own jobs and bad at working together. DuoDesk fixes that. Put a Mac and a Windows PC side by side and use them with one mouse and keyboard. Open the PC's apps on the Mac. Turn an old laptop or your Android tablet into a second screen. Answer your phone's calls and texts from the computer, use its camera in a video call, and paste on one device what you copied on another.
💻 ComputersOne mouse and keyboard · second screen · the other computer's apps in windows · files · clipboard · camera · sound · terminal |
📱 Phones and tabletsCalls · texts · photos · files · camera · remote and gamepad · screen and apps in windows · tablet as a second screen |
📡 ConnectionsSame Wi-Fi · USB cable · Bluetooth · Wi-Fi Direct and hotspot links made on demand · picked for you, moved for you |
🚀 Get startedDownload · open on both · pair once with a code · turn on what you want · privacy: no account, no telemetry |
🐧 Linux and 🤖 Android in detailX11 and Wayland · shared folders through Samba · the phone app page by page · wireless debugging, set up once |
🛠 Under the hoodHow it works · build and run on macOS, Windows, Linux, NixOS and Android · GitHub Actions |
|
🍎 macOS |
🪟 Windows |
🐧 Linux
|
🤖 Android
|
DuoDesk is free and has no paid Apple Developer ID or Windows code-signing certificate, so macOS and Windows don't know who made it and ask once before opening it. The source is all here.
🍎 macOS
You do this once; updates open normally. If macOS says DuoDesk is damaged and can't be opened, it isn't: run this in Terminal, then open it again:
xattr -dr com.apple.quarantine /Applications/DuoDesk.app
🪟 Windows
On Windows 11 with Smart App Control on, unsigned apps are blocked with no Run anyway button. The only way past it is turning it off (Windows Security › App & browser control › Smart App Control settings), and on many Windows 11 versions it can't be turned back on without reinstalling Windows.
🤖 Android
The full app (notifications, texts and Accessibility) is easiest installed by the computer over wireless debugging (Phone page › Notifications from the phone): Android then lets you turn those on. Installed by hand, Play Protect may block it, and Android 13 and later grey out notification access and Accessibility as a restricted setting: open Settings › Apps › DuoDesk, tap ⋮ › Allow restricted settings, then turn them on.
Every file and older version is on the releases page.
Your phone is now a camera, a remote and a gamepad. Use its camera in any video call, drive your computer from the couch, or play with it as a controller. Copy pictures and screenshots across every screen, and lock the pointer to one computer with a key.
| What's new | ||
|---|---|---|
| 📷 | Camera. The phone's camera, or the other computer's, in a window or as a webcam for Zoom, Teams and Meet | More |
| 🎮 | Remote and gamepad. A touchpad and keyboard for the computer, and a controller it sees as a real one | More |
| 🖼 | Pictures on the clipboard. Copy a screenshot on the PC, paste it on the Mac or the phone | More |
| 🔒 | Cursor lock. Scroll Lock keeps the pointer on the computer it's on | More |
| 🎵 | Media controls. What's playing on the phone, with play, pause and skip on the computer | More |
| 🪶 | Lighter. Every feature off until you turn it on, and about half the memory in the tray | More |
Thanks to everyone who sent pull requests for this release: see Thanks.
Older releases: 2.2 brought DuoDesk Mesh, 2.1 brought Bluetooth and Wi-Fi Direct and the phone's calls, texts, photos and files. Every release's notes are on the releases page.
The same app on every platform, so a Mac and a PC pair just like two Macs.
Push the pointer off the edge of your screen and keep working on the other computer, as if they were one. Your keyboard follows the pointer. Trackpad gestures (Spaces swipes, pinch to zoom, show desktop) carry over, and a double-tap of the hotkey brings everything home. Set which side the other computer is on, edge resistance and pointer speed.
Cursor lock (new in 2.3) keeps the pointer on the computer it's on, even the one the mouse isn't plugged into: press Scroll Lock (F14 on a Mac), or use the Cursor tab or the tray / menu bar.
Extend your Mac onto a PC or another Mac with a real virtual display, or mirror it. Or bring the other computer's screen into a window and control it from there. Low-latency H.264 with Fastest and Smooth playback, and optional frame generation.
Open a Windows app on your Mac (or a Mac app on your PC) and it gets a window of its own, with its own Dock icon or Start-menu pin. No full remote desktop, just the app you need, next to your own.
Show the other computer's camera in a window, or send it to a webcam every app can pick: DuoDesk Camera in Zoom, Teams, Meet or the browser. A computer shares its camera only when you turn on Let … see this camera on it, and a popup there says who is watching. The same works with a phone's camera.
The virtual camera installs the first time you turn it on: a Windows 11 camera (one administrator prompt), v4l2loopback on Linux (one password prompt), and on the Mac it goes into OBS Virtual Camera (or DuoDesk's own camera extension, in builds signed for it).
Drag files across the screen edge and drop them anywhere, or copy with ⌃⌥C and
paste with ⌃⌥V (Ctrl+Alt+C/V on Windows and Linux), into a folder or straight
into the app in front. Send from the macOS Share menu or Explorer's Send to, or share a folder
that shows up as a network drive on the other side. Files on their way show live progress.
Need a shell? ssh duodesk opens one on the other computer, no passwords needed.
Copy on one computer and paste on the other, instantly or when you switch over. Pictures go too (new in 2.3), up to 10 MB: take a screenshot with Win+Shift+S on the PC and paste it on the Mac. Entries from password managers are skipped, and a Recent list keeps the last few things you copied, pictures with a preview.
See one computer's notifications on the other as native notifications, and hear one computer's sound on the other. Wake a sleeping computer with Wake-on-LAN, and every switch you flip is shared by both sides and remembered for the pair.
Pair as many computers and phones as you like. Switch moves the session to another paired device nearby, Take over claims one that's busy with someone else, and Disconnect lets go. All from the Overview, the menu bar or the tray.
Your laptop, your desktop, the Linux box in the corner and your phone, all connected at once, each talking straight to the others with no hub in between.
Mesh works on Windows, Mac and Linux: turn it on in the Multi-device tab, and off again any time with everything as you left it. Connecting just two devices? You won't need it. Still coming to Mesh: pictures on the clipboard, and files dragged to more than one device at a time; the phone connects to one computer at a time, and Linux joins over the same Wi-Fi only.
Most phone links stop at notifications and a file drop. In DuoDesk your Android phone or tablet is a full peer: it pairs like a computer and gets the same features, plus its calls, texts, photos, files and camera.
Answer, decline and make your phone's calls from the computer. When it rings, a small window shows who's calling with Answer and Decline. With Bluetooth, the computer becomes the phone's headset, so you talk and listen right there. The Calls page has a number pad, your contacts and the call history.
Read and reply to your texts on Messages: every conversation, pictures included, and a count in the sidebar.
Browse the phone's photos and videos on Photos, open any of them big, and save one or many to the computer. Phone Files browses the phone's whole storage: save, upload, rename, delete, or just drop files on the page. Shared folders work both ways: a folder the phone shares opens in Finder, Explorer or the Linux file manager, and one the computer shares shows up in the phone's Files app.
The phone's back or front camera, in a window on the computer or as the DuoDesk Camera webcam in any video call. Switch cameras and rotate the picture from the Camera tab, or start it from the phone's own Camera page.
The phone's Remote page turns it into the computer's remote, for the couch or a presentation:
Turn on Remote on the computer to let the phone drive it.
What's playing on the phone shows in its card on the Overview, with its art, Previous, Play/Pause, Next and a bar to seek. On Windows and Linux, Play phone sound here makes the computer the phone's Bluetooth speaker.
See your phone's screen in a window and control it with your mouse, trackpad and keyboard. Better still, open single Android apps in windows of their own, side by side with your desktop apps. Pin them to the Dock or the Start menu and use them like any other app. In WhatsApp, Instagram and Telegram, Enter sends.
Turn a tablet or phone into an extra monitor. Extend for more desktop space, or Mirror to show what's on your screen. Use touch as the mouse, or switch on touchpad mode.
The Android app adapts to the device: tabs at the bottom on a phone, a full sidebar on a tablet. Every page names the computer you're connected to and shows what's shared in each direction.
You never have to choose. DuoDesk uses the same network when there is one, moves a phone onto the USB cable when you plug it in, and falls back to Bluetooth when the Wi-Fi goes: on a train, or in a café whose guest Wi-Fi blocks devices. The link and its latency are always shown at the top of the app (38 ms · Bluetooth).
Bluetooth is great for the session but too slow for a screen or a big file. So when you start one, DuoDesk brings up a direct Wi-Fi link between the two devices for as long as it's needed, then goes back to Bluetooth. Press Connect with Wi-Fi Direct to keep it, or let the computer join the phone's hotspot.
| Same Wi-Fi | USB cable | Bluetooth | + Wi-Fi Direct or hotspot | |
|---|---|---|---|---|
| Session, clipboard text, notifications | ✅ | ✅ | ✅ | ✅ |
| Mouse and keyboard, remote | ✅ | ✅ | ✅ | ✅ |
| Calls and texts | ✅ | ✅ | ✅ | ✅ |
| Screens, apps, cameras, files, photos, clipboard pictures | ✅ | ✅ | moves to Wi-Fi Direct | ✅ |
Terminal between computers (ssh duodesk) |
✅ | — | on Wi-Fi Direct | ✅ |
Who can turn up over Bluetooth is up to you: Bluetooth with phones (on) and Bluetooth with computers (off until you want it), on the Overview and in General.
For the phone's screen, apps and camera in windows, DuoDesk walks you through turning on Android's wireless debugging once (details). Files, clipboard, calls and photos work without it. The phone's notifications, texts, media controls and mouse and keyboard through Accessibility come with the full app, which the computer installs once over wireless debugging.
| Pair | What you get |
|---|---|
| Mac ↔ Windows PC, Mac ↔ Mac, PC ↔ PC | Every computer feature |
| Linux ↔ Mac, PC or Linux | Every computer feature (a few differences) |
| Android ↔ Mac, Windows or Linux | Every phone and tablet feature (Real gamepad on Windows and Linux) |
| All of them at once | DuoDesk Mesh |
DuoDesk only talks to devices you've paired with, directly over your own network, Bluetooth, a direct Wi-Fi link or a cable. There are no accounts, no telemetry and no cloud relay. Your calls, texts, photos and camera go straight from the phone to your computer and nowhere else. The only internet request is an update check against GitHub's public releases, which you can turn off.
Everything below is for the curious and for people building DuoDesk themselves.
On Linux, DuoDesk runs on both X11 and Wayland. On Wayland, the mouse and keyboard go through evdev and uinput (the Setup screen grants access once), and screens are captured through the desktop portal. A few things work a little differently:
Install DuoDesk on the phone, open it next to DuoDesk on the computer and pair from Overview › Nearby. The phone needs Android 10, and Android 11 for everything that goes through wireless debugging.
The app is laid out like the computers' (a sidebar on tablets, tabs at the bottom on phones), and every page names the computer it's connected to:
| Page | What it does |
|---|---|
| Overview | The computer you're connected to, Connect and Disconnect, nearby computers to pair with, and the wireless debugging card until that's set up |
| Screen | Use the phone as a screen for the computer: Mirror, or Extend the desktop onto it. Touch works as the mouse (tap to click, hold to right click, drag to select or move windows, two fingers to scroll), with the computer's sound and Smooth playback |
| Cursor | The computer's mouse on the phone across the screen edge, its pointer speed here, reverse scrolling, right and middle click |
| Keyboard | The computer's keyboard types on the phone, every key as a key, so any layout works and the soft keyboard stays out of the way. A keyboard on the phone types on the computer |
| Remote | The phone as the computer's touchpad and keyboard, or as a gamepad: keys of your choosing, a real controller (Windows, Linux), or a Bluetooth gamepad for any computer |
| Camera | The phone's back or front camera on the computer, and whether its virtual camera takes it |
| Clipboard | Copy on one, paste on the other, each way on its own switch, at once or when sent |
| Notifications | The phone's notifications on the computer, with the text hidden if you like, and the computer's on the phone |
| Files | Send files, copy them to paste on the computer, and see where the computer's files land |
| Sound | The phone's sound on the computer, and the computer's sound on the phone |
| General | The phone's name, background running, and the permissions DuoDesk uses, each with its switch |
| About | Source code, releases, the license, and what goes over wireless debugging and the network |
And outside the app:
Files, the clipboard and notifications work right away. The phone's screen, its apps in windows, touch, your mouse and keyboard on the phone and its sound go through wireless debugging, which DuoDesk pairs with once:
.DS_Store and ._ files never land on the phone.
Each computer runs an Electron app, which handles the window, pairing, the link and the state machines. Next to it runs a small native helper for everything the OS keeps to itself: capturing and injecting input, virtual displays, gestures, window capture and native drag and drop.
| Folder | What's in it |
|---|---|
mac/ |
macOS app (Electron) |
mac-helper/ |
macOS helper (Swift): virtual display, event tap, input injection, audio, apps, SMB |
windows/ |
Windows app (Electron) and installer |
windows-helper/ |
Windows helper (C#): hooks, SendInput, Raw Input touchpad, window capture, native drag |
linux/ |
Linux app (Electron) |
linux-helper/ |
Linux helper (C): XInput2 / XTest on X11, evdev / uinput on Wayland, XRandR, window list, XDND edge strip |
android/ |
Android app (Kotlin, Jetpack Compose); the computers drive the phone through adb and scrcpy's server |
shared/ |
Used by every app: the wire protocol, the Bluetooth pipe and Wi-Fi Direct links, the phone hub (Calls, Messages, Photos, Phone Files), shared folders, frame generation and icons |
The link between two devices is one TLS session wherever it runs: on the local network, through
a phone's USB cable (adb), or through Bluetooth LE (a GATT pipe of DuoDesk's own,
shared/blepipe.js). When a session on Bluetooth needs bandwidth, shared/netlink.js brings up a
Wi-Fi Direct group or joins a phone's hotspot, moves the session onto it, and takes it down
again once nothing needs it. Calls, Messages, Photos and Phone Files are shared/phonehub.js on
the computers, answered by DuoDesk on the phone.
Files between two computers on the network or a cable stream over HTTPS on the same port, beside the
control link and up to four at a time (shared/fastfile.js), so mouse and keyboard never wait
behind a big file. Through Bluetooth, Wi-Fi Direct, a hotspot, or with an older TwinDesk on the
other side, they go as before: in pieces on the control link.
Ports: TCP 47800 (control link and files) and UDP 47801 (discovery) on the local network.
You need Node.js 18+ on every platform.
xcode-select --install # Swift compiler for the helper
cd mac
npm install
npm run build:helper
npm start # run from source
npm run dist && npm run dmg # build DuoDesk.app and DuoDesk-<version>-<arch>.dmg in mac/dist/
The disk image is named after the app inside it: DuoDesk-2.4.0-arm64.dmg for Apple Silicon,
DuoDesk-2.4.0-x64.dmg for Intel. Keep those names on a release: the in-app updater picks the
one for each Mac by them.
By default, npm run dist targets the Mac's current architecture. To build an Intel
package from an Apple Silicon Mac, use:
npm run dist:x64 && npm run dmg
To build the Intel app and its image in one step, run npm run dmg:intel; it writes
mac/dist/DuoDesk-<version>-x64.dmg.
Use npm run dist:arm64 && npm run dmg for Apple Silicon explicitly. The x64 build
cross-compiles the Swift helpers and packages the x64 Electron runtime, so it does
not require an Intel Mac.
On first launch, DuoDesk asks for Screen Recording, Accessibility and Input Monitoring (once; after that the General tab shows each permission's status).
npm run dist signs the app with a certificate of its own, made the first time in
~/.twindesk-signing (keep a backup). macOS keeps permissions per signature, so with the same
certificate they carry over when an update is dragged into Applications. An app built without it is
signed ad-hoc, and macOS treats every update as a new app; DuoDesk then clears the stale entries so
Allow works again.
cd windows
npm install
npm run build:helper :: uses the .NET Framework C# compiler that ships with Windows
npm start
npm run dist :: NSIS installer in windows\dist\
npm run dist -- arm64 :: the Windows on ARM installer (or `x64 arm64` for both)
npm run dist also works on a Mac or Linux: it skips the helper build and packages the
macshare-winhelper.exe already in windows-helper\bin\ (for example, one taken from a release).
The installer adds the firewall rules (for every network profile, so a standard account on a Public network doesn't need an administrator later). The Setup screen, shown once, offers to fix the firewall if something changed (that needs an administrator) and to install the optional Virtual Display Driver for Extend.
sudo apt install build-essential libx11-dev libxi-dev libxtst-dev libxext-dev libxrandr-dev libxfixes-dev
cd linux
npm install
npm run build:helper
npm start
npm run dist # AppImage and .deb in linux/dist/
The Setup screen walks you through the rest. On Wayland that means input access (one admin
prompt, then log out and back in once). It can also install OpenSSH for the terminal. Extend on
GNOME Wayland uses Python 3 with GObject and GStreamer's PipeWire plugin (python3-gi,
gstreamer1.0-pipewire), which GNOME desktops already have.
DuoDesk includes a flake.nix with package, dev shell, and NixOS module support:
# Run directly with flakes
nix run github:0xCodez/DuoDesk
# Or enter development environment
nix develop
On NixOS, enable the module in your system configuration:
{
programs.twindesk = {
enable = true;
user = "yourusername"; # adds to input/uinput groups for Wayland KVM
};
}
See docs/nixos.md for full options (firewall, Wi-Fi Direct capability wrappers, virtual displays, and more).
linux/scripts/vm-test.sh runs it in a Parallels Desktop Linux VM
(Ubuntu with the packages above and Node.js): it copies this checkout into the VM, builds the
helper, starts DuoDesk in the VM's desktop session and drives it from the Mac.
linux/scripts/vm-test.sh start # sync, build and (re)start it in the VM
linux/scripts/vm-test.sh shot linux.png # screenshot of its window
linux/scripts/vm-test.sh eval "UI.go('cursor')"
linux/scripts/vm-test.sh log
On the VM's shared network it finds the Mac's DuoDesk and pairs like any Linux computer.
cd android
./gradlew assembleRelease # JDK 17+; app/build/outputs/apk/{standard,full}/release/
standard is the build people download. full adds notification access, the SMS permissions
(Messages) and the Accessibility service (mouse and keyboard without wireless debugging), which Play Protect blocks in downloaded apps; the computers install it over wireless debugging (Phone page ›
Notifications from the phone), so npm run dist on each platform bundles the newest
android/dist/*-full.apk.
Build Android, Build Linux and Build Windows (Actions tab › Run workflow) make the
standard and full APKs, the AppImage and .deb, and the x64 and arm64 installers, helpers included.
Set the ANDROID_KEYSTORE secret to the key the Android app is signed with
(base64 -i ~/.android/debug.keystore): the APKs then install over existing ones, and the Linux and
Windows builds carry the full Android app. Without it the APKs get the runner's own key and the
computers' builds leave the Android app out.
To Authenticode-sign the Windows installers, set the WIN_CSC_LINK secret to a base64-encoded
Windows code-signing .pfx certificate and WIN_CSC_KEY_PASSWORD to its password. Keep the
certificate and password out of the repository. When WIN_CSC_LINK is set, the Windows build fails
if signing cannot complete instead of silently publishing an unsigned installer. Signing gives
users a verified publisher and can help SmartScreen reputation build over time; it does not
guarantee that antivirus products will stop flagging a file.
DuoDesk builds on TwinDesk, which is better for everyone who sent it a pull request (links go to the TwinDesk repository):
And thanks to everyone who reports problems and shares ideas in the issues.
DuoDesk is made by 0xCodez (source, website). It is a fork of TwinDesk by Inuka Asith, released under the GNU GPL v3.0; DuoDesk keeps that licence and every original copyright notice.
DuoDesk is free software, licensed under the GNU General Public License v3.0. Copyright © 2026 0xCodez; based on TwinDesk, Copyright © 2026 inukaasith.
Parts are adapted from DeskPad (MIT). See THIRD_PARTY_NOTICES for details.