chorrent
Send files and folders directly between devices, from Rust. No server in between and no size limit. If several devices have the same file, a download pulls different parts from all of them at once, and every downloader helps pass it on.
Built on iroh (encrypted QUIC connections that get through home routers, with a relay server as a fallback).
- Every piece is checked (BLAKE3) as it arrives. A damaged or tampered piece is rejected and fetched again, so a finished download is exactly what was shared.
- Files and folders, any size.
- Swarms: download from many sharers at once. Sharers find each other automatically.
- Resumes interrupted downloads, and remembers shares across restarts.
- Private shares and contact allowlists: only the people you choose can download.
- Encrypted storage for apps that must not leave files readable on disk.
- Runs on your app's own iroh endpoint, if you already have one.
- Works on Windows, macOS, Linux and Android.
Quick start
use ;
async
A share code is a short piece of text starting with chr2. Send it any way you like.
Whoever has it can download the share (add allowlists if that's not enough).
The main pieces
Client::builder() |
Settings: a folder to remember things in (data_dir), speed limits, encrypted storage, an existing iroh endpoint |
client.seed(path) / seed_with(path, options) |
Share a file or folder. Options: private, allow_peers, join another sharer's swarm |
client.seed_reader(name, size, reader, options) |
Share a stream instead of a path, e.g. an Android content URI |
client.download(&code, dest) / download_with |
Download. Returns a handle with events(), cancel() and finished() |
client.saved() / resume() / forget() / remove() |
Pick up shares and unfinished downloads after a restart |
client.read_range() / export_file() |
Read or save files kept in encrypted storage |
client.network_status() / check_peers(&code) |
Find out why something won't connect |
Event covers peers connecting and leaving, pieces arriving, swarm status and more, and can
be turned into JSON (serde) for a UI in another process.
Using your app's own iroh endpoint
If your app already runs iroh, give chorrent the same endpoint, so transfers use the same
identity, relay server and connections. Add chorrent::ALPN to the endpoint's ALPNs and pass
matching incoming connections to client.handle_connection(conn). In your accept loop,
finish each handshake in its own task: awaiting it inline lets one slow peer hold up every
other connection.
let client = new;
The full example is in the repository README.
Features
mainline: also find devices through the BitTorrent Mainline DHT (ClientBuilder::mainline_dht). Only relay addresses are published, never IP addresses.
Requirements
Rust 1.88 or newer, a tokio runtime, and iroh 1.0.3 or newer (if you bring your own endpoint).
License
Apache-2.0