s3nd
- Durée
- 4 semaines
- Date
- Août – septembre 2026
- Site web
- s3nd.sh
- Documentation
- doc.s3nd.sh
- Démo en ligne
- drop.s3nd.sh
- Code source
- GitHub


+13
Préambule
$ s3nd put ./report.pdf
report.pdf · 284 kB · expires in 1 day
K7QP2M4X
# sur n'importe quelle autre machine
$ s3nd get k7qp-2m4x
Wrote /home/you/report.pdf · 284 kB
s3nd envoie n'importe quoi avec un code, via votre propre bucket. Les octets vont d'une machine à un bucket S3 qui vous appartient, puis du bucket à l'autre machine. Rien ne transite par le serveur de quelqu'un d'autre, personne ne crée de compte et il n'y a rien à déployer. Huit caractères, quarante bits, ni I, ni L, ni O, ni U : lisez-le au téléphone, tapez-le dans la mauvaise casse avec un tiret au milieu, il se résout quand même.
La même brique fonctionne à l'intérieur d'une app. Une app local-first garde tout dans IndexedDB, puis l'utilisateur l'ouvre sur un nouveau téléphone et elle est vide. s3nd enveloppe cet état dans un snapshot auto-descriptif et compressé en gzip, le range sous un code, et l'utilisateur tape ce code sur le prochain appareil. Les identifiants restent sur le serveur ; le navigateur ne parle qu'à l'API de l'app.
Le projet a commencé sous le nom bucketcode, une petite librairie que j'ai extraite de TripBrain. Elle s'est enrichie d'une CLI, de hooks React, d'un protocole et d'une boîte de dépôt : elle a donc été renommée s3nd et déplacée dans un monorepo avec tout son historique. L'ancien dépôt est archivé et bucketcode est déprécié sur npm au profit des paquets @s3nd/* ; un snapshot écrit par bucketcode se relit toujours.
Liens utiles
- s3nd.sh, le site : ce que c'est, les trois façons de l'utiliser, cas d'usage, fournisseurs, comparatifs
- doc.s3nd.sh, la documentation : démarrage rapide, CLI, protocole, référence de l'API
- drop.s3nd.sh, la boîte de dépôt en ligne : un petit WeTransfer sur votre propre bucket
- Déployer votre propre boîte de dépôt sur Vercel, en un clic
- Code source sur GitHub, licence MIT
- Sur npm : @s3nd/cli, @s3nd/core, @s3nd/react, @s3nd/protocol
Stack technique
- TypeScript, Node.js 20+, builds ESM et CommonJS avec types embarqués
- AWS SDK v3 pour S3, compatible AWS S3, Cloudflare R2, MinIO, Scaleway, Wasabi
- Hooks React 19, Next.js 16 App Router, Tailwind 4
- Fumadocs pour le site de documentation, shiki pour les exemples de code générés au build
- Workspaces bun, Turborepo, tsup, Vitest
- GitHub Actions, release-please, provenance npm, Vercel
Trois façons de l'utiliser
- Depuis un terminal,
@s3nd/cli:init,doctor,put,get,rm, directement vers le bucket ou via votre propre serveur avec--remote - Dans votre app,
@s3nd/corecôté serveur et@s3nd/reactdans le navigateur : un seul fichier de route transforme n'importe quel bucket en boîte de dépôt - Tout ce qui parle HTTP,
@s3nd/protocol: quatre routes, un format d'erreur, un client typé qui s'embarque dans un navigateur parce qu'il ne contient aucun client de stockage.curlfonctionne
En détail
L'architecture suit une contrainte : un navigateur ne doit jamais se retrouver avec un client de stockage dans son arbre de dépendances. @s3nd/protocol est le contrat que partagent les deux côtés, c'est pourquoi il existe en paquet séparé plutôt que dans @s3nd/core. Les hooks React dépendent du protocole, jamais de S3.
@s3nd/protocol nanoid le contrat, partagé par tout
@s3nd/core + aws-sdk, protocol la brique S3
@s3nd/react + protocol, react (peer) les hooks, aucun chemin vers S3
@s3nd/cli + core le binaire
Les codes sont toute l'expérience utilisateur d'un transfert. Génération et normalisation viennent de la même configuration, si bien qu'elles ne peuvent jamais être en désaccord sur l'alphabet. Les caractères ambigus sont retirés de l'alphabet et réparés à la saisie : k7qp-2m4x se résout en K7QP2M4X. Le serveur choisit le code et le réserve avec une écriture conditionnelle, pour que deux expéditeurs ne puissent jamais revendiquer le même.
s3nd doctor est ce qui tient la promesse du « premier transfert en deux minutes ». Il effectue chaque opération dont s3nd a besoin sur le vrai bucket et rapporte ce qui s'est passé : identifiants, accessibilité, aller-retour écriture, lecture et suppression, et présence d'une règle de cycle de vie qui nettoiera réellement les transferts expirés.
Chaque snapshot porte sa propre version d'enveloppe, distincte de la version de schéma de l'app, et maxVersion refuse un snapshot écrit par un schéma plus récent. La compression est détectée à partir des octets magiques gzip plutôt que supposée, ce qui permet aux snapshots écrits par l'ancien bucketcode de se charger encore.
Rôle
Projet solo : conception produit et API, les quatre paquets, la CLI, le site et son identité, la documentation, le template de boîte de dépôt, les exemples et le pipeline de publication.
Ce que j'ai construit
Les paquets
@s3nd/core: snapshots, fichiers et un handler de transfert au-dessus de S3, avec des codes d'erreur stables et une expiration appliquée à la lecture@s3nd/cli: le binaires3ndavec des profils, des références.envplutôt que des secrets dans la config, le code sur stdout et le reste sur stderr, pour queCODE=$(s3nd put ./report.pdf)se compose@s3nd/react: des hooks pour envoyer un fichier ou un snapshot, et un champ de saisie de code qui répare ce que l'utilisateur a tapé@s3nd/protocol: le contrat réseau, un client basé sur fetch et les codes, sans client de stockage
La boîte de dépôt
- Un petit WeTransfer sur votre propre bucket, en ligne sur drop.s3nd.sh et déployable en un clic comme template Vercel
- Aperçu avant l'envoi : image, vidéo, audio, PDF, premières lignes d'un texte
- Options par transfert : durée de vie, mot de passe haché avec scrypt, destruction après le premier téléchargement, nom personnalisé, un message
- Page de retrait avec QR code, et le même protocole à quatre routes pour que la CLI puisse s'y connecter
Site et documentation
- s3nd.sh : un site Next.js bilingue (EN / FR) entièrement statique, avec une identité de tableau d'affichage à palettes, des cas d'usage, des guides par fournisseur et des pages comparatives, plus un
llms.txt - doc.s3nd.sh : 22 pages de documentation, du démarrage rapide au protocole, aux limites, aux tests et à des cas d'usage comme la synchronisation chiffrée
- Un film de lancement de 56 secondes, celui en haut de cette page, entièrement généré par du code : chaque image dessinée sur un canvas à 60 fps par Chromium headless, la bande-son synthétisée à partir de sinusoïdes et de bruit, les deux pilotées par la même feuille de montage pour que chaque palette claque sur l'image où elle tourne
- Des démos animées pour tout le parcours et pour chaque paquet, enregistrées à partir de la vraie sortie de la CLI
Tests et publication
- Une suite de tests hors ligne de plus de 230 cas contre un double S3 en mémoire qui respecte les en-têtes conditionnels, exécutée sur Node 20, 22 et 24 en CI
- release-please piloté par les commits conventionnels, quatre paquets versionnés indépendamment, publiés sur npm avec provenance
Réalisations techniques
Une librairie devenue un produit
bucketcode résolvait un problème étroit. s3nd garde ce cœur intact, les snapshots écrits par bucketcode se relisent toujours, et construit autour les outils qui le rendent utilisable par tous : une commande de terminal, des hooks React, un protocole, une boîte de dépôt et un site.
Votre bucket, le serveur de personne d'autre
Pas de relais, pas de compte, pas de politique CORS à écrire, rien à signer dans le navigateur. Les identifiants restent là où ils doivent être et le code est toute la poignée de main.
En résumé
s3nd est une façon open source de faire passer un fichier ou tout l'état d'une app d'un appareil à un autre avec un code de huit caractères, via un bucket que vous possédez déjà. Essayez-le sur drop.s3nd.sh, lisez la documentation, ou npm install -g @s3nd/cli.






