Cross-platform AirDrop. Send files, photos, folders and text between iPhone, Android, and any other device — over the same Wi-Fi, with no app store, no accounts, and no cables. Bytes travel directly device-to-device over an encrypted WebRTC channel; the server only introduces the devices to each other and never sees your data.
It runs as an installable web app (PWA): open it in a browser, "Add to Home Screen," and it launches like a native app on iOS and Android, in light or dark to match the system.
Deploy it (permanent URL) or wrap it native (Capacitor) → DEPLOY.md. Honest store-submission reality → PUBLISHING.md.
| ✅ | Files & photos, both directions, iOS ↔ Android ↔ desktop |
| ✅ | Multi-select and whole-folder sending (folder picking on Android; multi-file on iOS) |
| ✅ | Resumable transfers — if the connection drops mid-file, it reconnects and resumes from the acknowledged byte (no duplication) |
| ✅ | Text & link sharing — type a message, the other device gets a tap-to-copy card |
| ✅ | QR pairing — point the other device's normal camera at the code; no in-app scanner needed |
| ✅ | Private rooms — pair across networks with a shared word; the server only ever sees its hash, never the word |
| ✅ | Encrypted in transit — WebRTC DTLS, always on |
| ✅ | Local notifications for incoming transfers while backgrounded |
| ✅ | Android share-sheet target — share from any app straight into Beam |
| ✅ | Installable PWA, adaptive light/dark, offline app shell |
git clone https://github.com/Abdullajon1881/beam.git
cd beam
npm install # one runtime dependency: ws
npm start # http://localhost:3000Open http://localhost:3000 to confirm it loads.
Browsers require HTTPS for "install to home screen", notifications, and reliable WebRTC. The quickest HTTPS address without a domain or cert is a free tunnel. With the server running, in a second terminal:
cloudflared tunnel --url http://localhost:3000 # no account needed
# or: npx localtunnel --port 3000Open the printed https://… URL on both devices. On the same Wi-Fi they
discover each other automatically — tap a device, choose Photos & Files / Folder
/ Send Text. For a permanent URL, see DEPLOY.md.
Tap Pair (top-right) → enter a shared word (e.g. sunflower) on both
devices, or scan the QR with the other device's camera. Only devices with the
same word can see each other, and the word never leaves your device — the server
only receives its SHA-256 hash.
View an Android device's screen on the iPhone and tap/swipe to control it. The
iPhone side is built into Beam (the Mirror & Control action appears on any
device advertising caps=host); the Android device runs the companion app in
beam-host/, which captures its screen
(MediaProjection → WebRTC) and injects taps via an AccessibilityService.
The web (viewer) side is covered by tests; the native host app needs to be built and run on real hardware — see its README for the build + test plan. (Note: Google scrutinizes accessibility-based remote control on the Play Store — see PUBLISHING.md.)
iPhone ──┐ 1. both connect (WebSocket) ┌── Android device
├────────────── signaling ──────────────────┤ server only relays
│ (server.js, matchmaker) │ the SDP/ICE handshake
│ │
└──────── 2. direct WebRTC data channel ─────┘
file bytes go device-to-device, DTLS-encrypted,
never through the server
public/
index.html app shell
config.js runtime config (server host, optional TURN)
styles/ design tokens (Apple HIG colors/type) + components
js/
app.js entry: registers SW, boots UI
ui.js controller: peers, transfers, sheets
signaling.js WebSocket signaling client
transfer.js WebRTC engine: queue, folders, text, resume
remote.js remote-screen viewer/controller
rtc.js shared ICE config (STUN + optional TURN)
crypto.js private-room hashing (SHA-256, on-device)
qr.js + vendor/ QR rendering for pairing
sheets.js iOS-style bottom sheets
notify.js local notifications
icons.js, dom.js helpers
sw.js app-shell cache + Android share-target handler
server.js static server + WebSocket signaling (rooms by IP or hash)
beam-host/ Android companion app for screen mirror/control (Kotlin)
The web app is plain ES modules — no build step, no framework. npm run check
syntax-checks every module; CI also runs a server smoke test.
- File bytes never touch the server — peer-to-peer WebRTC, DTLS-encrypted.
- The signaling server only relays SDP/ICE; private-room passphrases are hashed on-device (the server sees only the hash).
- Responses set a strict CSP and standard security headers; signaling messages are size-capped and rooms are bounded.
Some things are blocked by iOS at the OS level and no app can do them:
- ❌ Texts / SMS / iMessage or placing calls from a non-Apple device.
- ❌ Tapping or controlling an iPhone from another device (the reverse — controlling Android from iPhone — is supported, see the bonus above).
Pulling an iPhone's photo library on demand or one-way iPhone-screen viewing are possible but require a native iOS app (an Apple Developer account; build in the cloud if you don't have a Mac).
See CONTRIBUTING.md. PRs welcome — run npm run check first.
MIT.