Your devices' clipboards and shared folders, reachable from any of them. One owner, no account, end-to-end encrypted. Linux and Android.
Run a node on each device. Each one publishes an index of the folders you chose to share; the others cache it. From any device you browse and search every other device's shares — even while they're asleep — and when you open a file its bytes stream over on demand, by content hash, with range requests. On Android it shows up as a storage location in every app's file picker, so attaching a file that lives on your desktop is just… picking it. It works the other way too: the phone's chosen folders are browsable from the desktop, a sleeping phone is woken by push when you open one, and the photo you just took is already in the desktop's clipboard overlay.
Built on iroh: QUIC, hole-punching, encrypted relay
fallback through an anchor (relay + wake + blind mailbox; ours by default, self-hostable), iroh-blobs for verified range-able transfer, iroh-gossip for
announcements. Not a file sharing app: a network filesystem for one person,
with the clipboard as its recents view.
Status: M1 — desktops pair, gossip sealed and signed manifests, and browse each
other's shares from cache; a clipboard history with an on-demand overlay
(reach clip), synced between paired desktops, works on wlroots-style compositors. reach get copies files and
directories from another device, resumably (M2); the FUSE mount, the anchor and Android are next. See docs/roadmap.md.
- Architecture — concepts, layers, flows, security model, Android mapping
- Tech stack — every choice and what it beat
- Development setup — dependencies,
devenv, commands, crate boundaries - Roadmap — milestones as runnable demos
- ADRs — the decisions that shape the design
- Android app — module plan, provider manifest, build steps
crates/reach-core pure contracts: identity, manifest, clip, announce (tested)
crates/reach-files filesystem capability: safe root scanning (tested)
crates/reach-net iroh endpoint + blobs + gossip + control ALPN
crates/reach-engine the rules and the api vocabulary, no I/O
crates/reach-store sqlite: seq, members, shares, cached manifests, clip history
crates/reach-node the running node every host embeds
crates/reach-ipc versioned contract between the CLI/overlay and the daemon
crates/reach-clipboard clipboard rules: flavors, secrets, history, pictures
crates/reach-clipboard-linux Wayland data-control agent, run inside the daemon
crates/reach-daemon the always-on provider for Linux (`reach daemon`)
crates/reach-cli the command surface, over the daemon's unix socket
crates/reach-ffi uniffi bindings for Android
crates/reach-clip-ui clipboard overlay: layer-shell, CPU-drawn, started on demand
crates/reach `reach` — the one binary all three roles ship in (ADR-0016)
android/ Kotlin app: DocumentsProvider + Compose (M4)
docs/ architecture, tech stack, roadmap, ADRs
Crates point inward from platform adapters to a shared application engine and portable capability libraries; see ADR-0007.
just doctor # verify the minimum Rust toolchain
just check # cargo check --workspace
just test # cargo nextest run (or cargo test)
just ci # formatting, check, lint, tests, dependency policy
just daemon documents=$HOME/Documents # bind, scan, print the manifest
reach --help # the intended CLI surface
Clipboard, in sway (any wlroots-style compositor has an equivalent). The daemon has to run inside the Wayland session, since it is what watches the clipboard:
just install # one binary, `reach`, into ~/.cargo/bin
exec reach daemon # in ~/.config/sway/config: starts with sway
bindsym $mod+v exec reach clip # opens the overlay; the same key closes it
reach clip list | fuzzel -d | reach clip decode | wl-copy # cliphist-style
reach clip import cliphist # bring your cliphist history across
reach clip starts the daemon itself if nothing is listening, so the exec line is
only there to have it up before the first copy.
The overlay is fully keyboard-driven (F1 lists the keys). For vim keys, put
keys = "vim" in ~/.config/reach/clip-ui.toml.
- Publish the index, fetch the bytes — manifests are pushed and cached; file bytes are pulled on demand. Browse offline, fetch when reachable.
- One owner — membership is the entire authorization model. Sharing with other people is a different product.
- Phones provide, on wake — no always-on endpoint on a phone; the anchor wakes it by push, and new photos are pushed to the desktop eagerly (ADR-0009).
- Directories are per-file manifests — never archives; symlinks are never followed.
- Android via DocumentsProvider + proxy fd — every app gets your desktop's files; reads are range requests, so video seeks.
- The UI is the OS, except the clipboard — FUSE and SAF behind the file managers you have; one layer-shell overlay for clipboard history, because Linux has none — started on demand and drawn on the CPU, so it costs nothing while closed.
- Anchor: public by default, self-hostable — relay, wake sender and mailbox; holds no mesh secret, never stores file bytes. Phones are woken via UnifiedPush, with FCM through our push gateway as the embedded fallback (ADR-0008).