![]()
A free, open-source peer-to-peer file transfer app for Windows + Android. Built on Rust, Tauri 2, iroh QUIC, iroh-blobs, and BLAKE3.
◆ no upload step ◆ no account ◆ no artificial file-size cap ◆ no telemetry ◆ no cloud bucket ◆
Download · Website · AUDIT.md · Roadmap · Changelog · Security
In 30 seconds. Lightning P2P sends a file by handing the receiver a tiny ticket (NodeId + content hash). The receiver pulls the bytes directly from the sender's device over an encrypted iroh QUIC connection. No upload step. No cloud bucket. BLAKE3 verifies every chunk as it lands. When NAT blocks the direct path, iroh relay carries the encrypted frames — still no plaintext on any server.
| ✓ Best fit | ✗ Not for |
|---|---|
| Moving large builds, databases, media between Windows machines | Browser-only transfer (web is handoff, not the engine) |
| Windows ↔ Android sideload testing | macOS / Linux production (planned, not shipped) |
| Sharing without cloud accounts, upload caps, or hosted retention | AirDrop protocol compatibility |
| Open-source workflows that need inspectable artifacts + checksums | Phone-to-phone NFC writing (NFC receive only) |
| Honest benchmark methodology with committed evidence | "Fastest in the world" marketing claims |
Stable: v0.4.6. Experimental: v0.7.0 (BBR congestion control, Warp mode, swarm receive, ticket pre-warming; carries v0.5.x speed modes + BLE/NFC).
| Platform | Asset | Channel | Best for |
|---|---|---|---|
| Windows | LightningP2P-win-Setup.exe |
Stable | Most users · one-click Velopack |
| Windows | LightningP2PSetup.exe |
Stable | Classic NSIS |
| Windows | LightningP2P.msi |
Stable | Policy-managed deployments |
| Android | LightningP2P-android-latest.apk |
Stable | Android 10+ sideload (signed) |
| Experimental | Release v0.7.0 | Pre-release | BBR engine · Warp mode · swarm receive · pre-warm |
◆ Verify your install before you trust it (click to expand)
# Windows — checksums and Authenticode
powershell -ExecutionPolicy Bypass -File .\scripts\verify-release.ps1 `
-Installer .\LightningP2P-win-Setup.exe `
-Checksums .\SHA256SUMS.txt
# Android — file hash + signer certificate
(Get-FileHash .\LightningP2P-android-latest.apk -Algorithm SHA256).Hash
Get-Content .\SHA256SUMS-android.txt | Select-String "LightningP2P-android-latest.apk"
apksigner verify --print-certs --verbose .\LightningP2P-android-latest.apk
The signed Android APK's signer certificate fingerprint:
5F:A0:D6:63:46:FF:9C:91:1B:18:D1:2A:5F:77:F1:F0:9B:2D:E2:A7:69:A0:97:68:6C:FC:FA:43:BD:86:29:16
Full trust guide: docs/download-trust.md.
flowchart LR
subgraph Sender [Sender · native app]
F[files on disk] --> I[iroh-blobs
add + hash]
I --> T[BlobTicket
NodeId + hash]
end
subgraph Path [encrypted iroh QUIC · direct → relay]
D{{direct route
signal-green}}
R{{relay fallback
NAT-traversal hop}}
end
subgraph Receiver [Receiver · native app]
G[iroh-blobs
download] --> V[BLAKE3
verify per chunk] --> O[destination dir]
end
T -.QR / link / paste.-> G
Sender --> D --> Receiver
Sender --> R --> Receiver
classDef sender fill:#08120f,stroke:#7ddf9c,color:#7ddf9c,stroke-width:1.5px
classDef receiver fill:#08120f,stroke:#7ddf9c,color:#7ddf9c,stroke-width:1.5px
classDef path fill:#050706,stroke:#f0c76b,color:#f0c76b,stroke-width:1px
class Sender sender
class Receiver receiver
class Path path
NodeId + content hash + format).Handoff URLs use /receive#t=<ticket> — the ticket lives in the URL fragment, so it never reaches the website server.
Six session-level transfer modes. Each swaps a complete transport profile: congestion controller, QUIC send/recv/stream windows, initial congestion window, MTU-discovery ceiling, max streams, keepalive, import concurrency, idle timeout, UI emit cadence. Persists across launches; node restarts on change (deferred if a transfer is in flight).
| Mode | Engine | Parallelism | Emit | Conn win | Stream win | Streams | Init cwnd | MTU probe | Default for |
|---|---|---|---|---|---|---|---|---|---|
| Battery Safe | CUBIC | 8 | 250 ms | 64 MB | 16 MB | 256 | 14.7 KB | 1452 | Android |
| Standard | CUBIC | 64 | 100 ms | 256 MB | 64 MB | 1024 | 14.7 KB | 1452 | Desktop |
| Fast | BBR | 128 | 100 ms | 256 MB | 64 MB | 1024 | 256 KB | 1452 | — |
| Extreme | BBR | 128 | 200 ms | 512 MB | 128 MB | 2048 | 1 MB | 8952 | — |
| LAN Beast | BBR | 128 | 200 ms | 1024 MB | 256 MB | 4096 | 4 MB | 8952 | — |
| Warp | BBR | 128 | 200 ms | 2048 MB | 512 MB | 8192 | 8 MB | 8952 | — |
Why BBR matters: quinn (iroh's QUIC engine) defaults to loss-based CUBIC, which halves its window on packet loss — devastating on lossy Wi-Fi and high-bandwidth paths. Upstream iroh measured CUBIC up to ~30× slower than BBR on the same LAN path (n0-computer/iroh#4286). Fast and above run BBR; Standard keeps CUBIC so the default behavior stays unchanged. MTU probing above 1452 targets jumbo-frame LANs — quinn binary-searches the path and black-hole detection recovers safely on networks that can't carry large datagrams.
Swarm receive experimental — folder transfers normally fetch files one at a time over a single stream, paying a round trip of dead air per file. With swarm receive, the receiver first grabs the tiny content index, then fans the files out over parallel direct connections — on by default in Extreme (8-wide), LAN Beast (12-wide), and Warp (16-wide), and forceable for every mode in Settings. Every byte stays BLAKE3-verified in the same store, and any failure falls back to the standard path automatically — it is never worse than the default.
Honest scope. The congestion-controller switch is evidence-based (upstream measurements); window/stream/parallelism sizing encodes design intent. On same-machine loopback the modes cluster within ~13% (626 – 710 Mbps median) because loopback is CPU-bound, not congestion-bound. LAN/WAN throughput-delta validation lands in v0.6.
Mode-sweep receipts:
AUDIT.md §2.1.1·docs/reports/raw/audit-v0.5.1/mode-sweep/.
The bench tool lives at src-tauri/src/bin/benchmark_local.rs. It generates payloads at runtime (xorshift PRNG), spins up two LightningP2PNode instances in temp dirs, and runs the real sender::create_share + receiver::receive_ticket paths.
Current reference — same-machine loopback, AMD Zen 5 + Windows 11 Build 26200 + NVMe, 5 runs each, schema v2:
| Scenario | Runs | Median total | Export | Effective |
|---|---|---|---|---|
same_machine_10mb |
5/5 | 147 ms | 7 ms | 569.89 Mbps |
same_machine_100mb |
5/5 | 1,356 ms | 7 ms | 618.45 Mbps |
same_machine_1gb |
5/5 | 13,565 ms | 8 ms | 633.21 Mbps |
same_machine_many_small (200 × 100 KB) |
5/5 | 512 ms | 274 ms | 327.05 Mbps |
Caveat: Same-machine loopback only. Not WAN. Not Windows ↔ Android. Not Wi-Fi. Not relay. Don't quote these for "fastest" claims.
◆ Reproduce locally
# Smoke (10 MB only · ~30s)
pnpm bench:local
# Full (10 MB / 100 MB / 1 GB / many-small)
pnpm bench:local:full
# Direct — with explicit mode + hardware notes
.\src-tauri\target\release\benchmark-local.exe `
--profile full --runs 5 --mode standard `
--hardware-notes "AMD Zen 5, Win 11 26200, NVMe" `
--output-dir docs/reports/raw/local
Raw JSON + CSV: docs/reports/raw/. Methodology + template: docs/BENCHMARKS.md · docs/benchmark-report-template.md.
Lightning P2P avoids cloud file hosting, but receive tickets are capability tokens. Anyone with a valid ticket can request the content while the sender is online — treat tickets like secrets.
| Property | How |
|---|---|
| Transport | Every byte encrypted by iroh's QUIC stack. TLS 1.3 keys derived per-session. |
| Integrity | BLAKE3 verifies as the receiver streams to disk. Bad bytes surface as structured errors, never silent corruption. |
| Storage | Sender keeps the file on disk until receive completes. There is no upload step to a hosted bucket. |
| Relay | Connectivity help (a hop when NAT blocks the direct path). Not retention. Relay sees encrypted QUIC frames, not plaintext. |
| Diagnostics | Bundles gathered locally, redacted, copied by the user. The frontend never auto-posts transfer secrets. |
| Telemetry | None by default. The native app does not phone home. |
| Sender contract | Keep the sender online until receive finishes. Closing the app cancels in-flight transfers. |
Read SECURITY.md · docs/security-model.md · docs/download-trust.md before using on sensitive machines.
| Capability | Status | |
|---|---|---|
| 🟢 | Windows send + receive (Tauri 2 desktop) | Stable |
| 🟢 | Android send + receive (sideload APK) | Stable |
| 🟢 | Android system share-target | Stable v0.4.6 |
| 🟢 | Android MediaStore routing (Pictures / Movies / Music / Downloads) | Stable v0.4.6 |
| 🟢 | QR + handoff link + raw ticket | Stable |
| 🟢 | Nearby Wi-Fi / LAN discovery (mDNS) | Stable |
| 🟢 | iroh relay fallback when direct path is blocked | Stable |
| 🟢 | Atomic single-blob writes (.part + rename) |
Stable v0.5.1 |
| 🟢 | Retry + exponential backoff on transient receive errors | Stable v0.5.1 |
| 🟢 | Implicit resume across restarts (re-paste ticket) | Stable (iroh-blobs persistent store) |
| 🟡 | Speed modes (6 profiles, BBR on Fast+) | Experimental v0.7.0 |
| 🟡 | Swarm receive (parallel fetches, default-on in Extreme+, auto-fallback) | Experimental v0.7.0 |
| 🟡 | Ticket pre-warming (pre-dial on paste) | Experimental v0.7.0 |
| 🟡 | BLE proximity discovery (Android + Windows) | Experimental since v0.5.0 |
| 🟡 | NFC ticket receive (Android) | Experimental since v0.5.0 |
| ⏳ | Explicit resume UI for failed transfers | Planned v0.6 |
| ⏳ | Phone-to-phone NFC write, macOS/Linux BLE | Roadmap |
| ⏳ | macOS / Linux / iOS desktop builds | Roadmap |
BLE and NFC never carry file bytes — beacons + ticket material only. Bytes always travel through iroh QUIC. Full behavior + hardware test plan: docs/proximity.md.
``` src/ React + TypeScript marketing + receive shell src/components/WebLandingPage.tsx cinematic landing (Cabinet Grotesk, motion-led) src/components/ReceiveHandoffPage.tsx /receive#t= handoff
src-tauri/ Rust backend · Tauri 2 IPC · iroh engine src-tauri/src/node/
$ claude mcp add lightning-p2p \
-- python -m otcore.mcp_server <graph>