# transfqr — full content for LLM ingestion > File transfer between two devices over QR codes. No internet, no servers, no accounts. This file concatenates the public-facing content of transfqr.com so an LLM can answer questions about the project from a single fetch. Last updated: 2026-05-01. --- ## What it does The sender picks a file. The app deflates it (if helpful), splits it into K source blocks, and starts streaming **fountain-coded QR frames** on screen at ~7 frames per second. The receiver opens its camera, reads whichever frames it can, and reconstructs the file once it has K + ε symbols. No pairing, no internet, no cloud, no account. ## Why fountain codes A naive cycle of QR codes (chunks 1…N, then loop) requires the receiver to either acknowledge what it has captured or restart on every miss. transfqr does not have a back-channel — the sender's screen and the receiver's camera are one-way. **Luby Transform (LT) codes** solve this. The sender produces an *infinite stream* of XOR-combined symbols, each one a random subset of the source blocks XOR'd together. The receiver only needs to capture any K + ε of these symbols (where ε is a small overhead, ~5%) to solve the file using belief propagation. No retransmits, no acknowledgments, no restart on a missed frame. This is the same family of erasure codes used in broadcast satellite protocols, IETF FECFRAME, and 5G MBMS. In transfqr v1 we use LT codes; v2 will use RaptorQ (RFC 6330) for slightly lower decode-failure overhead. ## Wire protocol summary Every QR code carries a binary frame, base64-encoded: - 18-byte header: magic 'TQ', version, packet type (meta or data), 32-bit fileId, 32-bit totalChunks K, 16-bit blockSize, 32-bit PRNG seed. - Payload: meta packet (filename, MIME, original size, SHA-256 of padded payload, compression flag) or data packet (LT-encoded block of `blockSize` bytes). Sender alternates: every 10th frame is a meta packet (so a late-joining receiver can bootstrap), the rest are LT data symbols with fresh random seeds. ## How it differs from other file transfer methods | Trait | transfqr | AirDrop | Bluetooth | Cloud sync | | ------------------------------ | -------- | ------- | --------- | ---------- | | Internet required | No | No | No | Yes | | Bluetooth on | No | Yes | Yes | No | | Wi-Fi on | No | Yes | No | Yes | | Cross-platform iOS ↔ Android | Yes | No | Yes | Yes | | Cross-device laptop ↔ phone | Yes | Yes | No | Yes | | No account needed | Yes | Yes | Yes | No | | Air-gapped friendly | Yes | No | No | No | transfqr is slower than a real network. The trade-off: when the air around you is a network you can't use (airplane mode, kiosk, regulated environment, dead Wi-Fi), it's the one that still works. ## CLI ``` $ transfqr ./photo.jpg transfqr · 312 chunks, ~1 min of streaming. ctrl+c stops. file photo.jpg size 148.6 KB (deflate) chunks 312 @ blockSize 512 frame 00027 point a phone running transfqr at this terminal. [ QR rendering ] ``` Installation: - One-liner: `curl -fsSL https://transfqr.com/install.sh | sh` - npm: `npm i -g transfqr` or `npx transfqr ` The CLI shares all protocol code with the mobile app — both speak the same wire protocol. You can stream from a Linux laptop and receive on an iPhone. ## File-size limits - Hard cap: 50 MB. Above this the app refuses — QR-over-camera tops out at ~7 frames/sec, so larger files take impractically long. - Soft warning: 5 MB. Above this the app shows a confirmation with an estimated minute count. ## Privacy - **No servers.** There is no transfqr backend. Bytes never leave the two devices. - **No accounts.** No email, no phone number, no identifier. - **No telemetry by default.** Anonymous analytics (PostHog) are opt-in via a consent screen on first launch. Even when on, only mode-selected, transfer-start/complete/abort events with bucketed file-size and bucketed duration are sent. Never file names, contents, hashes, or IP. - **Crash reports** (Sentry) are opt-in and contain stack traces + anonymous device metadata only. ## Permissions - **Camera** — receiver scans QR codes from the sender's screen. - **Storage** — sender reads the source file, receiver writes the reconstructed file to the app sandbox. - **Photos** — receiver auto-saves received images and videos to the system camera roll. Asked the first time an image is received; can be declined; other file types go through the share sheet instead. - **Vibration** — haptic feedback on transfer events. ## Roadmap - RaptorQ erasure coding (replaces LT codes for higher efficiency) - End-to-end encryption with passphrase - Multi-file transfer sessions - iOS Live Activity / Dynamic Island progress