I Got Tired of "How Do I Send You This File?" So I Built QuickDrop
Every developer has been there. You need to send a folder to someone. Maybe it's a build artifact, a dataset, some photos from your phone, or a project directory.
Your options? Upload to Google Drive and wait. Zip it and email it (if it's under 25 MB). Set up an S3 bucket. Use WeTransfer. Bluetooth. AirDrop (Apple only). USB stick.
All of them require either an account, a cloud service, a size limit, or the same ecosystem.
I wanted something dumber and faster:
machine-a$ quickdrop receive
machine-b$ quickdrop send ./photos --to AB3C4E7E:X9K2
Done. Files transferred. No accounts. No uploads. Encrypted end-to-end.
That's QuickDrop.
The 30-Second Version
Install it:
npm install -g quickdrop
On the receiving machine, run:
$ quickdrop receive ./downloads
quickdrop - receive
--------------------------------------------
LAN code AB3C4E7E:X9K2 <- same network
Tunnel code quick-fox-42:X9K2 <- anywhere
Password X9K2 <- new every session
--------------------------------------------
Waiting for sender... (Ctrl+C to stop)
On the sending machine, paste the code:
$ quickdrop send ./photos --to AB3C4E7E:X9K2
✓ DSC_001.jpg (4.20 MB, 11.3 MB/s)
✓ DSC_002.jpg (3.85 MB, 12.1 MB/s)
✓ raw/DSC_003.cr2 (18.40 MB, 11.8 MB/s)
--------------------------------------------
✓ 3 files - 26.4 MB - 2.3s - 11.7 MB/s
That's it. One command on each side. The combined code AB3C4E7E:X9K2 encodes both the address and a one-time password, so the sender has zero prompts.
Why Not Just Use scp/rsync?
You absolutely can. But:
- scp/rsync need SSH access. The receiver needs an SSH server running, a user account, firewall rules, open ports. QuickDrop needs nothing pre-configured.
-
scp doesn't work across NATs. If you and your friend are on different WiFi networks, you can't
scpto them without port forwarding or a VPN. QuickDrop automatically tunnels through NAT when needed. - scp requires knowing the IP. QuickDrop encodes the address into a short alphanumeric code you can read over the phone or paste into Slack.
QuickDrop is for the use case where you want to send files to a person, not deploy to a server.
How It Actually Works
There's no relay server storing your files. Here's what happens under the hood:
On the Same Network (LAN) -- direct, peer-to-peer
QuickDrop opens a TCP server on the receiver and encodes its local IP + port into an 8-character base-36 code. The sender decodes the code, connects directly via TCP, and streams files at full LAN speed. No internet involved. This is true peer-to-peer -- nothing between the two machines.
Across the Internet -- relayed, but end-to-end encrypted
When sender and receiver are on different networks, QuickDrop spins up a localtunnel WebSocket bridge. The receiver gets a public *.loca.lt subdomain. The sender connects to that subdomain over WSS. Traffic is relayed through localtunnel infrastructure, but every byte is AES-256-GCM encrypted before it enters the tunnel -- the relay sees only ciphertext and never stores anything.
This is not peer-to-peer in the strict sense (there's no NAT hole-punching), but your files are never readable by the relay, and nothing is persisted on any server.
Both codes (LAN and tunnel) are displayed automatically. Use whichever one works.
Encryption
All file data is encrypted with AES-256-GCM before it hits the wire. The 4-character session password is never transmitted -- both sides independently derive a 256-bit key using scrypt (N=16384, r=8, p=1), then prove they have the same key via an HMAC-SHA256 handshake.
Each message uses a fresh random IV, so identical files produce different ciphertext every transfer. GCM's authentication tag means any tampering or corruption is detected and the transfer aborts.
Wire format per message:
[4-byte length prefix][12-byte IV][16-byte auth tag][ciphertext]
Is a 4-character password breakable? In theory, yes -- there are ~1.7 million possible 4-char alphanumeric passwords. But scrypt with these parameters takes ~100ms per attempt, making brute-force cost ~47 hours of CPU time. And the password changes every session. For a file transfer tool (not a bank vault), this is a practical tradeoff between security and usability.
Things I Deliberately Didn't Build
- No accounts. No signup, no login, no API keys.
- No cloud storage. On LAN, files go directly between machines. Over the internet, traffic is relayed through an encrypted tunnel -- but nothing is stored on the relay, and the relay can't decrypt your data.
- No GUI. It's a CLI tool. If you want a GUI, you're looking for AirDrop.
-
No configuration files. It works out of the box. The only persistent state is an optional contacts file at
~/.quickdrop/contacts.json. - No file size limits. It streams in 64 KB chunks. Send 10 bytes or 10 GB.
Contacts: The One Piece of State
After a transfer, the sender is prompted to save the receiver as a named contact:
Save "192.168.1.42" as a contact? Name (Enter to skip): workpc
✓ Saved! Next time: quickdrop send ./folder --to workpc
Next time:
quickdrop send ./logs --to workpc --password X9K2
That's it. Contacts are a flat JSON file. You can manage them:
quickdrop contacts # list
quickdrop contacts rename workpc office
quickdrop contacts remove office
The Stack
The entire thing is ~500 lines of JavaScript across 7 files:
| File | What it does |
|---|---|
cli.js |
Arg parsing, subcommand dispatch |
src/sender.js |
Connect, authenticate, stream files |
src/receiver.js |
TCP server, WS bridge, auth, write files |
utils/framing.js |
Length-prefixed message framing |
utils/crypto.js |
AES-256-GCM, scrypt, HMAC |
utils/codes.js |
IP-to-base36 encoding |
utils/contacts.js |
Contact book persistence |
Two runtime dependencies: ws for WebSocket support and localtunnel for NAT traversal. Everything else is Node.js built-in (net, crypto, fs, path).
Try It
# Install
npm install -g quickdrop
# Or just run it once
npx quickdrop help
Requires Node.js 18+. Works on Linux, macOS, and Windows.
Test it on your own machine with two terminals:
# Terminal 1
quickdrop receive ./test-output
# Terminal 2 (paste the code from terminal 1)
quickdrop send ./some-folder --to <CODE>
Source code: github.com/real-kijmoshi/quickdrop
npm: npmjs.com/package/quickdrop
Website: quickdrop.kijmoshi.xyz
QuickDrop is ISC licensed. It scratches a very specific itch: sending files to someone without ceremony. If that itch is yours too, give it a shot.
Top comments (0)