s3nd
- Duration
- 4 weeks
- Date
- August – September 2026
- Website
- s3nd.sh
- Documentation
- doc.s3nd.sh
- Live demo
- drop.s3nd.sh
- Source code
- GitHub


+13
Preface
$ s3nd put ./report.pdf
report.pdf · 284 kB · expires in 1 day
K7QP2M4X
# any other machine
$ s3nd get k7qp-2m4x
Wrote /home/you/report.pdf · 284 kB
s3nd sends anything with a code, through your own bucket. The bytes go from one machine to an S3 bucket you own, and from the bucket to the other machine. Nothing streams through anyone else's server, nobody signs up for anything, and there is nothing to deploy. Eight characters, forty bits, no I, L, O or U: read it over the phone, type it in the wrong case with a dash in the middle, it still resolves.
The same primitive works inside an app. A local-first app keeps everything in IndexedDB, then the user opens it on a new phone and it is empty. s3nd wraps that state in a self-describing, gzipped snapshot, stores it under a code, and the user types the code on the next device. Credentials stay on the server; the browser only ever talks to the app's own API.
The project started as bucketcode, a small library I extracted from TripBrain. It grew a CLI, React hooks, a wire protocol and a drop box, so it was renamed s3nd and moved to a monorepo with its full history. The old repository is archived and bucketcode is deprecated on npm in favour of the @s3nd/* packages; a snapshot written by it still reads back.
Useful links
- s3nd.sh, the website: what it is, the three ways in, use cases, providers, comparisons
- doc.s3nd.sh, the documentation: quick start, CLI, protocol, API reference
- drop.s3nd.sh, the live drop box: a small WeTransfer on your own bucket
- Deploy your own drop box on Vercel, in one click
- Source code on GitHub, MIT licence
- On npm: @s3nd/cli, @s3nd/core, @s3nd/react, @s3nd/protocol
Stacks involved
- TypeScript, Node.js 20+, ESM and CommonJS builds with bundled types
- AWS SDK v3 for S3, compatible with AWS S3, Cloudflare R2, MinIO, Scaleway, Wasabi
- React 19 hooks, Next.js 16 App Router, Tailwind 4
- Fumadocs for the documentation site, shiki for build-time code samples
- bun workspaces, Turborepo, tsup, Vitest
- GitHub Actions, release-please, npm provenance, Vercel
Three ways in
- From a terminal,
@s3nd/cli:init,doctor,put,get,rm, straight to the bucket or through your own server with--remote - Inside your app,
@s3nd/coreon the server and@s3nd/reactin the browser: one route file turns any bucket into a drop box - Anything that speaks HTTP,
@s3nd/protocol: four routes, one error format, a typed client that bundles for a browser because it carries no storage client.curlworks
Details
The architecture follows one constraint: a browser must never end up with a storage client in its dependency tree. @s3nd/protocol is the contract both halves share, which is why it exists as its own package rather than inside @s3nd/core. The React hooks depend on the protocol, never on S3.
@s3nd/protocol nanoid the contract, shared by everything
@s3nd/core + aws-sdk, protocol the S3 primitive
@s3nd/react + protocol, react (peer) hooks, no path to S3
@s3nd/cli + core the binary
Sync codes are the whole user experience of a transfer. Generation and normalisation come from the same configuration, so they can never disagree about the alphabet. Confusable characters are removed from the alphabet and repaired on input: k7qp-2m4x resolves to K7QP2M4X. The server picks the code and reserves it with a conditional write, so two senders can never claim the same one.
s3nd doctor is what makes the "first transfer in two minutes" promise hold. It performs every operation s3nd needs against the real bucket and reports what happened: credentials, reachability, a write, read and delete round trip, and whether a lifecycle rule will actually clean up expired transfers.
Every snapshot carries its own envelope version, distinct from the app's schema version, and maxVersion refuses a snapshot written by a newer schema. Compression is detected from the gzip magic bytes rather than assumed, which is how snapshots written by the old bucketcode still load.
Role
Solo project: product and API design, the four packages, the CLI, the website and its identity, the documentation, the drop box template, the examples and the release pipeline.
What I built
The packages
@s3nd/core: snapshots, files and a transfer handler on top of S3, with stable error codes and expiry enforced on read@s3nd/cli: thes3ndbinary with profiles,.envreferences instead of secrets in config, stdout for the code and stderr for the rest, soCODE=$(s3nd put ./report.pdf)composes@s3nd/react: hooks to send a file or a snapshot, and a sync code input that repairs what the user typed@s3nd/protocol: the wire contract, a fetch-based client and sync codes, with no storage client
The drop box
- A small WeTransfer on your own bucket, live at drop.s3nd.sh and deployable as a one-click Vercel template
- Preview before sending: image, video, audio, PDF, first lines of text
- Per-transfer options: lifetime, password hashed with scrypt, burn after the first download, custom name, a message
- Pickup page with a QR code, and the same four-route protocol so the CLI can talk to it
Website and documentation
- s3nd.sh: a bilingual (EN / FR), fully static Next.js site with a split-flap departure-board identity, use cases, provider guides and comparison pages, plus
llms.txt - doc.s3nd.sh: 22 documentation pages, from the quick start to the protocol, limits, testing and use cases such as encrypted sync
- A 56-second launch film, the one at the top of this page, rendered entirely from code: every frame drawn on a canvas at 60 fps by headless Chromium, the soundtrack synthesised from sine waves and noise, both driven by the same cue sheet so each split-flap tile clicks on the frame it flips
- Animated demos for the whole journey and for each package, recorded from the CLI's real output
Testing and releases
- An offline test suite of more than 230 cases against an in-memory S3 double that honours conditional headers, run on Node 20, 22 and 24 in CI
- release-please driven by conventional commits, four packages versioned independently, published to npm with provenance
Technical achievements
A library that became a product
bucketcode solved one narrow problem. s3nd keeps that core intact, snapshots written by bucketcode still read back, and builds the tools around it that make it usable by anyone: a terminal command, React hooks, a protocol, a drop box and a website.
Your bucket, nobody else's server
No relay, no account, no CORS policy to write, nothing to sign in the browser. The credentials stay where they belong and the code is the whole handshake.
In short
s3nd is an open-source way to move a file or an app's whole state from one device to another with an eight-character code, through a bucket you already own. Try it at drop.s3nd.sh, read the documentation, or npm install -g @s3nd/cli.






