Send files.
No bullshit.

End-to-end encrypted file transfers from your terminal. Direct on LAN, encrypted relay over the internet. No accounts, no cloud, no size limits.

View on GitHub npm package
$ npm install -g quickdrop
machine-a — receiver
$ quickdrop receive ./downloads
machine-b — sender
$ quickdrop send ./photos --to AB3C4E7E:X9K2

What you get

Everything you need, nothing you don't.

D2D

Direct on LAN

On the same network, files stream over a raw TCP connection. No servers, no relays, no internet round-trip. True peer-to-peer at full LAN speed.

E2E

End-to-end encrypted

AES-256-GCM encryption with scrypt key derivation. Every message uses a fresh random IV. The password never leaves your machine.

No size limits

Streams in 64 KB chunks. Send a 10-byte text file or a 10 GB dataset. No artificial caps, no compression, no waiting for uploads.

0

Zero config

No accounts, no API keys, no config files. Install it, run it. Works out of the box on Linux, macOS, and Windows.

LAN

LAN speed

On the same network? QuickDrop connects via raw TCP. Full LAN bandwidth, no internet round-trip, no tunneling overhead.

NAT

Works across NATs

Different networks? Traffic is relayed through a localtunnel WebSocket bridge, but encrypted end-to-end before it enters the tunnel. The relay sees only ciphertext and stores nothing.

How it works

Two commands. That's the whole workflow.

1

Receiver starts listening

Run quickdrop receive ./downloads. A TCP server opens on a free port. The local IP and port are encoded into an 8-character alphanumeric code. A random 4-character one-time password is generated. Both are displayed as a combined code you can paste or read aloud.

2

Sender connects with the code

Run quickdrop send ./photos --to AB3C4E7E:X9K2. The code is decoded into an IP + port (LAN) or tunnel subdomain (internet). The sender connects and proves it knows the password via an HMAC-SHA256 handshake — the password itself never crosses the wire.

3

Files stream directly

The sender scans the directory, sends an encrypted file manifest, then streams each file in encrypted 64 KB chunks. Directory structure is preserved. Progress, speed, and per-file status are shown in real time on both sides.

4

Done

Both sides print a summary. The sender is prompted to save the receiver as a named contact for next time. Run quickdrop send ./logs --to workpc and skip the code entirely.

Security model

Not a bank vault. But not a joke either.

Encryption AES-256-GCM

Every message (control and data) is encrypted with AES-256-GCM using a fresh random 12-byte IV. The authenticated encryption tag detects any tampering or corruption. The tunnel infrastructure only sees ciphertext.

Key derivation scrypt

The 4-character password + a random salt are fed into scrypt (N=16384, r=8, p=1) to produce a 256-bit session key. At ~100ms per attempt, brute-forcing all 1.7M combinations costs ~47 CPU-hours. The password rotates every session.

Authentication HMAC-SHA256

Both sides independently derive the session key and exchange HMAC-SHA256 proofs. The password never travels on the wire, not even as a hash. Three wrong attempts and the connection is killed.

No relay storage

On LAN, files go directly between machines with no intermediary. Over the internet, traffic passes through a localtunnel relay but is encrypted end-to-end before entering the tunnel. The relay can't decrypt your data and stores nothing.

Wire format per message:
4 B length 12 B IV 16 B auth tag N B ciphertext

Commands

The full API. This is all of it.

Send files

quickdrop send ./photos --to AB3C4E7E:X9K2

# Or step-by-step with prompts:
quickdrop send ./photos

# Using a saved contact:
quickdrop send ./logs --to workpc --password X9K2

Receive files

quickdrop receive ./downloads

# Keep listening for multiple transfers:
quickdrop receive ./downloads --keep

# Default directory (current dir):
quickdrop receive

Manage contacts

quickdrop contacts              # list all
quickdrop contacts remove mypc  # delete one
quickdrop contacts rename mypc workpc

Other

quickdrop help
quickdrop --version

# Run without installing:
npx quickdrop help