Every time I need to move a file between two machines, I open a terminal and immediately regret my life choices. scp requires SSH access on both ends. rsync does too. Spinning up a quick Python HTTP server means knowing the sender's IP and punching through a firewall. croc sidesteps all of it.
What It Is
croc is a command-line file transfer tool written in Go. The sender runs croc send file.tar.gz, gets a short code phrase back, and shares it with whoever needs the file. The recipient runs croc <code-phrase> on their end. The transfer happens — end-to-end encrypted, no port-forwarding needed, across NAT, on any platform. Windows, Linux, Mac, doesn't matter.
It's not magic. The trick is a relay server that handles the connection handshake, so you don't need a direct path between machines. But your content is encrypted using PAKE (Password-Authenticated Key Exchange) before it ever leaves your machine — the relay sees ciphertext, not your files.
Why It's Worth Your Time
What separates croc from similar tools like magic-wormhole (which directly inspired it):
Transfers resume. Drop a connection halfway through a 2 GB backup and it picks up where it stopped. That alone is worth the install.
Multi-file and folder support. Send a whole directory: croc send /path/to/folder. Exclude what you don't want: --exclude "node_modules,.venv".
Self-hostable relay. This is the part I care about most for self-hosters. By default, croc uses a public relay. But you can run your own in one command, and then your traffic never touches a third-party server.
Tor proxy. If you need it: --socks5 "127.0.0.1:9050".
Piping works. cat archive.tar.gz | croc send and croc --yes <code> > output.tar.gz both work cleanly. Good for scripts.
Hands On
Installation
On Arch Linux:
pacman -S croc
On Fedora/RHEL:
dnf install croc
Via the install script (works on most Linux distros):
curl https://getcroc.schollz.com | bash
Or build from source if you have Go 1.22+:
go install github.com/schollz/croc/v10@latest
Always verify the install script against the official repo before piping to bash.
Sending a file
croc send backup.tar.gz
Output:
Sending 'backup.tar.gz' (142 MB)
Code is: fix-artist-moon
The code phrase copies to your clipboard automatically.
Receiving it
On another machine — any OS:
croc fix-artist-moon
That's the entire interface. On Linux, croc hides the secret from process listings by default. If you're transferring on a single-user machine and find the env-var approach annoying, run croc --classic once to make the simpler behavior permanent.
Running your own relay
On a VPS or your home server:
docker run -d -p 9009-9013:9009-9013 \
-e CROC_PASS='yourpassword' \
docker.io/schollz/croc
Then every transfer uses your relay:
croc --relay "yourserver.example.com:9009" --pass yourpassword send file.tar.gz
Recipients also need to specify the relay. You can make it the default by setting CROC_RELAY in your shell config — check the official docs for the current env var names, as these can change between versions.
Honest Verdict
croc is not the fastest option. On a gigabit LAN, scp or rsync will outpace it — the encryption and relay overhead are measurable, and if both machines are on the same network you're routing through a relay unnecessarily. For bulk transfers between servers you have SSH access to, croc isn't the right tool.
But that's not the use case it's built for. croc earns its place when you need to move something between machines that can't reach each other directly — different networks, NAT, no shared SSH keys. That's where everything else falls apart and croc just works.
Self-hosting the relay removes the main trust concern (depending on a third-party server). At that point you have a solid, private file-drop system that's simpler to use than anything involving SSH keys, and it works for anyone you hand a code phrase to.
Go Try It
Install it. Send yourself a file from two different terminals on different networks. You'll understand why it exists in about 30 seconds.