Sling a file from one computer to another. Two commands, zero servers to run, zero configuration, encrypted end-to-end, direct whenever the network allows.
machine A: $ sling report.pdf # or: sling photos/ notes.txt · tar cz p | sling -
lava-planet-cactus-dice ← tell the other person this code
machine B: $ sling lava-planet-cactus-dice
Incoming: 1 file (12.4 MB)
Accept and download? [y/N] y
Received 'report.pdf' (12.4 MB) in 1.2s — verified ✓ (BLAKE3)
v0.1.0 is out. Single file, two commands, nothing else — see SCOPE.md for what's in and what's deliberately not, and the roadmap for what's next.
sling <path> [<path>…]sends files and directories (any mix), printing a four-word code;sling -sends stdin.sling <code>previews what's coming (names, sizes) and asks before downloading;-yskips the prompt,-o <dir>picks the destination,-o -streams a single file to stdout.- BLAKE3-verified streaming into atomic part-file + rename writes; direct peer-to-peer with encrypted relay fallback, zero flags either way.
- Safety defaults: collision pre-flight refuses to touch existing files before a single byte moves (exit 3;
--forceoverrides), hostile entry names from the network abort the whole transfer, nothing half-delivers. - One-shot by design: the sender exits after the first complete download; the code dies with the sender process.
Upgrading from v0.1: receiving now shows a preview and asks
Accept and download? [y/N]— pass-yfor the old immediate behavior. Exit code 4 means the prompt was declined.
Limitations (deliberate): symlinks and empty directories are skipped with a warning; trees of thousands of tiny files transfer slower than one big file (auto-archiving is on the backlog).
Honest answer: they're good tools, use them happily. sling exists because:
- Nobody runs a rendezvous server for you to depend on or donate to — discovery and relay ride on n0's public iroh infrastructure, and the crypto (sender identity derived from the code) doesn't need a broker in the middle.
- Verified streaming, not verify-after — every byte is checked against a BLAKE3 tree as it arrives; a corrupted or truncated transfer can never appear as your final file.
- A deliberately tiny surface — one positional argument, two flags (
--help,--version), no config, no accounts, no modes. Codes are single-use and die with the sender process (contrast croc's reusable-secret CVE-2023-43621).
Grab a binary from the latest release (static Linux x86_64, macOS arm64, Windows x86_64; verify with SHA256SUMS.txt), or build from source with Rust 1.97+:
git clone https://github.com/m-de-graaff/sling
cd sling
cargo install --path crates/sling-cli
The sender's keypair is derived from the four-word code (keyed BLAKE3), and its addresses are published through n0's DNS discovery. The receiver derives the same public key from the code, looks the sender up, learns the file's BLAKE3 hash over a tiny authenticated handshake, then streams the data over QUIC (TLS 1.3, keyed to the code-derived identity) — directly when hole-punching succeeds, via encrypted public relays otherwise. Every byte is verified against the hash as it arrives — built on iroh and iroh-blobs.
Treat the code like a password: anyone holding it while the sender runs can download the file once. The code dies when the sender exits.
| Code | Meaning |
|---|---|
| 0 | success |
| 1 | runtime failure (network, IO) |
| 2 | usage error (bad argument or code) |
| 3 | refused to overwrite an existing file |
| 4 | transfer declined at the confirmation prompt |
| 130 | cancelled with Ctrl-C |
v0.1 is a single file, two commands, nothing else. Directories, piping, -o, clipboard, QR codes and friends are deliberately later — the full list with reasoning lives in SCOPE.md.
MIT OR Apache-2.0, at your option.