Private file transfer, straight between two computers.
One command to send, one to receive.
fsend moves a file from one computer to another with as little ceremony as
possible. No account, no upload step, no ports to open — just two commands and a
short share code.
- Direct, with no network setup — on the same network or across NATs that can be hole-punched, the bytes go straight from sender to receiver. When no direct path exists, or a network blocks UDP, a relay over HTTPS (TCP 443) takes over. Nothing to configure.
- End-to-end encrypted — TLS 1.3 between the peers, authenticated by the share code through a PAKE (CPace) bound to the TLS session, over a post-quantum hybrid key exchange (X25519MLKEM768). Even the relay only ever sees ciphertext.
- Send anything — a file, a folder, several at once, a stdin stream, or a literal string.
- Resumable — if a transfer drops, the next send picks up where it left off, and re-sending a folder moves only the new or changed files.
- Optional password — gate any transfer with
--password. - Runs anywhere — one static binary for Linux, macOS, FreeBSD and Windows, on x86 and ARM. Self-host the pairing server if you like.
Linux, macOS, FreeBSD — x86 and ARM:
curl -fsSL https://getfsend.alzina.dev | shmacOS — if you prefer Homebrew:
brew install polius/tap/fsendWindows — run this in PowerShell:
irm https://getfsend.alzina.dev/windows | iexReleases are signed and verified on install — see Security → Release integrity.
Other install methods
From source:
go install github.com/polius/fsend/cmd/fsend@latestOr grab a release binary from the releases page.
Tab-completion (optional)
Add the line for your shell to its rc file ($PROFILE on PowerShell):
eval "$(fsend completion zsh)" # zsh
eval "$(fsend completion bash)" # bash
fsend completion fish | source # fish
fsend completion powershell | Out-String | Invoke-Expression # powershellSend a file, a folder, several at once, a stdin stream, or a literal string:
fsend backup.zip # a single file
fsend ./project # a whole folder
fsend a.txt b.txt c.txt # several files at once
pg_dump mydb | fsend # a stream from stdin
fsend --text "wifi: hunter2" # a literal string
fsend backup.zip --password # gated behind a password…and to receive:
fsend abc-defg-jkm # save to the current folder
fsend --yes abc-defg-jkm # skip the confirmation prompt
fsend --out ~/Downloads abc-defg-jkm # save to a specific folder
fsend --out - abc-defg-jkm | tar x # stream to stdout (a folder arrives as tar)One minute: pairing with a share code, then the local, direct and relay routes fsend races to move the bytes. Plays as an MP4 in your browser; prefer reading? See Architecture.
| Architecture | Three transfer modes, raced concurrently — and why |
| Security | Threat model — what the server can and cannot see |
| Usage | Every flag, env var, and exit code |
| Self-hosting | Run your own pairing server in three steps |
| Development | Build and test from source |
| Troubleshooting | Common errors and what to do about them |
| Comparison | fsend vs croc, magic-wormhole, sendme and LocalSend |
Bug reports and pull requests welcome — see Development to build from source, or open an issue.