Under the hood
How it works
File transfer between two browsers with no upload server. This page explains what that means, and where it stops being true.
In short
This site is one static page. It has no backend, no accounts and no database. One person creates a channel and gets an ID. The other person types that ID. Their browsers find each other and open a direct, encrypted connection. Files travel over that connection and nowhere else.
Step by step
- You create a channel. Your browser makes a random ID in the form
XXXX-XXXX(8 characters from a 32-symbol alphabet, about 40 bits). You become the host of that channel. - Your browser hashes the ID. It computes SHA-256 of the ID with a fixed prefix and keeps the first 32 hex characters. That is the room name. The ID itself is never sent anywhere.
- The other person enters the ID. Their browser computes the same room name. Using the open-source library Trystero, both browsers post small signaling notes to public Nostr relays, tagged with that room name. The notes are encrypted with the ID as password, so relays only see unreadable data.
- A direct connection opens. When the two browsers read each other's notes they set up a WebRTC connection. WebRTC data channels are encrypted in transit (DTLS).
- The host accepts exactly one person. The first joiner is accepted. Anyone who tries afterwards is told the channel is full and is ignored.
- Files go browser to browser. Each file is read in small pieces, sent over the data channel, and put back together in the other browser's memory. Nothing is sent to the site's host or to the relays, and nothing is written to a database.
- The channel closes for both of you. If either person clicks Leave, closes the tab, loses connection, or 60 minutes pass, the other side is told right away and the channel ends. There is no history to recover.
Who can see what
| Party | Can see | Cannot see |
|---|---|---|
| The other person | The files you send them, their names and sizes, your IP address | Anything else on your device |
| The site's host | That someone downloaded this page (IP, time) | IDs, file names, file contents |
| Nostr relays | Your IP, the hashed room name, encrypted signaling data | The ID, file names, file contents |
| STUN servers | Your IP, to help work out your public address | IDs, file names, file contents |
| The CDN | That the Trystero library was loaded (IP, time) | IDs, file names, file contents |
| Your network provider | That you connected to the peer and to relays, and how much data moved | File contents |
Known limits
- The ID is the only lock. Anyone who learns it before the right person joins can take the one free place. Share it over a channel you trust, and check that the person you meant to send to is the one connected.
- The two-user rule and the 60-minute timer are enforced by the browsers, not by a server. They are not a security boundary against someone who modifies their own copy of the page.
- Your IP is visible to the other person. That is how direct connections work. If that matters, this tool is not the right one.
- Both people must be online at the same time. Files can't wait for someone who isn't there.
- Some networks block it. There is no TURN relay, so strict firewalls, some mobile networks and some corporate Wi-Fi can stop the connection. Try another network.
- Files are held in memory while they arrive. That is why each file is limited to 1 GB. Save a file before you leave, because it disappears when the page closes.
- It depends on public services. If the public relays or the CDN that serves the Trystero library are down, connecting fails.
- It trusts the code you load. If the host or the CDN were compromised, the page could be altered. That is why the source is public and small.
Not for situations where your safety depends on anonymity. This tool keeps files off servers, not you off the network.
Source code
The whole project is two HTML files. Read it, check it, or host your own copy.