mtnFileShare
How it works Plans Prompt
Prompt

The prompt for running your own.

Hand this to an AI coding agent and you should get a FileShare you can host yourself: same features, same shape, on your own server. It describes what the service does and what it needs from you as its operator, not how this copy is written.

Build a self-hosted peer-to-peer file sharing web app called FileShare.

CORE IDEA
One device opens the site and creates a share link, shown as a QR code. A second device scans it, or pastes the link or the short code, and the two browsers connect directly to each other over WebRTC. Files and text messages travel over the encrypted data channel between the two browsers. My server never sees or stores them; it only relays the signaling messages needed to set the connection up, and optionally relays encrypted traffic when a direct path is impossible. No uploads, no database.

PAGES AND FLOWS
- Landing page: a headline and lede that explain the idea, a "Create a link" button, an "I have a code" form that accepts a pasted share link or the bare code, a trust row (no accounts, no uploads, encrypted, nothing stored), a QR preview card that opens the site on a phone, and a three-step "How it works" section.
- Share page at /s/{id}. While waiting: the QR code, the link, a Copy button, a native share button where the browser supports it, and a note that the tab must stay open. Once the peer joins: a "Connected" status pill, a Disconnect button, and a composer where the user chooses text or files. Files can be dragged in or picked, queued, removed, and sent as a batch. Show progress per direction and a summary banner when a batch finishes. Received files are held in the browser and offered as a Save link; received text shows as a card with Copy, Save as .txt and Share. When the peer leaves or the connection fails: a "gone" panel with the last connection state, Reconnect and Start over. Unknown or expired links show an expired message.
- A collapsible "Connection details" panel on the share page: which path was used (same network, direct across the internet, or relay), every candidate pair with its result and round-trip time, errors per ICE server, and a timestamped log of the negotiation.
- Privacy and Terms pages that describe the data flow honestly: nothing is stored about files, signaling metadata lives in memory only, the relay forwards encrypted packets it cannot read, and the operator login email is only used to send the login link.

ROOMS AND TRANSFER
- Rooms have random 10-character ids from an unambiguous alphabet, hold at most two participants, live in memory, and expire after 12 hours without activity.
- The second device to join initiates the WebRTC offer and opens the data channel. Candidates that arrive early are queued.
- On the ordered data channel: a metadata message, then fixed-size binary chunks, then an end marker; the receiver acknowledges each item. A text message is a single message with a size cap. One item in flight per direction, both directions at once, with backpressure on the sender's buffer.

CONNECTIVITY AND THE RELAY
- STUN for everyone, so devices on the same network or behind friendly NATs connect directly.
- A TURN relay for the cases where a direct path is impossible (strict NATs, mobile carriers, corporate networks). I run the TURN server myself next to the app, and using it costs nothing beyond my own bandwidth. The app hands out short-lived TURN credentials per room, generated from a shared secret; the server decides at the moment it hands out ICE servers.
- The relay is mine to use. Rooms created from one of my devices get the relay; rooms created by anyone else who finds the site are direct only, so strangers cannot burn my bandwidth. A setting can open the relay to every room if I decide I do not care.
- I mark a device as mine by logging in: I enter my operator email, the server checks it against the configured operator address and emails a single-use link that is valid for 15 minutes. Opening the link sets a signed pass cookie on that device. The page always answers "Check your inbox" whether or not the email matched. Throttle per email and per IP. No passwords, no identity framework, no user table.
- When no TURN server is configured every room is direct. When no mail sender is configured the login is not offered.

RUNNING IT MYSELF
- One web app container, a reverse proxy that terminates HTTPS, and a coturn container, started together with docker compose. WebRTC needs a secure context, so HTTPS in production is not optional.
- The app can live under a sub-path of an existing site, so every URL, redirect, asset and websocket must respect the path base and forwarded headers.
- Everything I operate is configuration: the TURN host and shared secret, the operator email, the mail sender credentials, the path base, and a persistent location for the keys that sign the pass cookie so a restart does not log my devices out.
- No client build step: plain JavaScript and one stylesheet, with the signaling client library as the only dependency.
- External services (TURN, mail) sit behind interfaces with no-op fallbacks; the services are covered by unit tests with fakes so I can run the suite without any of them configured.
Files travel directly between the two devices over an encrypted WebRTC channel. This server only introduces them. Plans · Terms · Refunds · Privacy