Skip to content
JaggedGemPublic

About

Riftsend is a browser-based end-to-end encrypted peer-to-peer file transfer app for sending huge files directly between devices, with resumable transfers and optional encrypted relay fallback.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Repository files navigation

Riftsend

Browser-based, end-to-end encrypted, peer-to-peer file transfer for very large files.

Riftsend aims to let one person send files directly to another person through the browser with no account, no cloud upload, strong end-to-end encryption, resumable transfers, and maximum practical speed. The app uses WebRTC DataChannels for browser-to-browser transfer, a small signaling server for connection setup, and an optional TURN relay when direct peer-to-peer connectivity is not possible.

What this project is trying to achieve

  • Send files across the internet from one browser to another.
  • Keep file contents end-to-end encrypted.
  • Avoid uploading files to the application server.
  • Support very large files by streaming blocks instead of loading entire files into memory.
  • Resume interrupted transfers using local checkpoints and verified block ranges.
  • Prefer direct peer-to-peer connections, with encrypted relay fallback when required.
  • Keep the core experience account-free and simple.

Honest privacy statement

Riftsend should not claim that bytes never touch any server in every case. The accurate claim is:

File contents are encrypted before leaving the sender browser. When direct WebRTC connectivity works, encrypted file bytes flow directly between browsers. When direct connectivity fails, encrypted bytes may pass through a TURN relay, but the relay must never receive the file decryption key.

The signaling server should only coordinate setup messages such as room membership, WebRTC offers/answers, ICE candidates, and temporary TURN credentials. It should not receive plaintext files, file keys, or persistent transfer history.

Planned monorepo layout

riftsend/
  apps/
    web/
      src/
        app/
        components/
        webrtc/
        transfer/
        crypto/
        storage/
        workers/
        protocol/
    signaling/
      src/
        index.ts
        rooms.ts
        turnCredentials.ts
        messageTypes.ts

  packages/
    protocol/
      src/
        messages.ts
        manifest.ts
        frames.ts
        constants.ts
    shared/
      src/
        result.ts
        byteUtils.ts
        rangeSet.ts

  docs/
    architecture.md
    protocol.md
    security.md
    roadmap.md
    repo-setup.md
    implementation-plan.md

  .github/
    ISSUE_TEMPLATE/
    workflows/

This repository intentionally separates the browser app, signaling server, and shared protocol definitions. The signaling server should remain small and should not contain file-transfer business logic.

Major components

Web app

Location: apps/web/

Responsibilities:

  • Sender and receiver UI.
  • File picker and drag-and-drop.
  • WebRTC peer connection setup.
  • Control and data channel management.
  • File block reading and frame sending.
  • Encryption/decryption through Web Crypto.
  • OPFS and IndexedDB storage for resumable receiving.
  • Transfer progress, speed, ETA, and error states.

Signaling server

Location: apps/signaling/

Responsibilities:

  • Create temporary rooms.
  • Pair one sender and one receiver.
  • Forward WebRTC offers, answers, and ICE candidates.
  • Expire inactive rooms.
  • Apply abuse/rate limits.
  • Optionally issue temporary TURN credentials.

The signaling server must not store or inspect file contents.

Shared protocol package

Location: packages/protocol/

Responsibilities:

  • Versioned protocol message definitions.
  • Manifest shape.
  • Frame header shape.
  • Protocol constants.
  • Validation helpers.

Shared utility package

Location: packages/shared/

Responsibilities:

  • Range set utilities.
  • Byte formatting utilities.
  • Result/error utility types.
  • Shared test helpers.

Core protocol model

Riftsend should use three conceptual transfer units:

  • File: the user-selected file.
  • Block: the processing unit used for compression, encryption, verification, and resume.
  • Frame: the network unit sent over the WebRTC DataChannel.

Recommended early defaults:

  • Block size: 4 MiB.
  • Frame size: 256 KiB.
  • Encryption: AES-GCM through Web Crypto.
  • Key derivation: HKDF-SHA-256.
  • First hashing option: SHA-256.
  • Later hashing option: BLAKE3 through WASM if benchmarks justify it.
  • First compression option: none.
  • Later compression option: per-block gzip through Compression Streams.
  • Future compression option: zstd through WASM if benchmarks justify it.

Development phases

  1. Create the monorepo and documentation.
  2. Build WebSocket room signaling.
  3. Establish a WebRTC DataChannel between two tabs.
  4. Send a small raw file with simple chunks.
  5. Add backpressure.
  6. Split control and data channels.
  7. Add app-level encryption.
  8. Move to blocks and frames.
  9. Add OPFS and IndexedDB storage.
  10. Add block-level resume.
  11. Add optional per-block compression.
  12. Add TURN relay fallback.
  13. Harden security and abuse protections.
  14. Add automated tests and benchmarking.
  15. Polish UI and prepare public alpha.

See docs/implementation-plan.md for the full step-by-step implementation plan.

Documentation

Suggested local setup

This project is planned around:

  • TypeScript.
  • Vite + React for the web app.
  • Node.js or Bun for the signaling server.
  • pnpm workspaces for monorepo management.
  • WebRTC DataChannels for peer-to-peer transfer.
  • Web Crypto for browser-native encryption.
  • OPFS and IndexedDB for resumable receiver-side storage.
  • coturn for TURN relay fallback.

The exact commands are documented in docs/repo-setup.md.

Project status

Planning stage.

The first milestone is a minimal WebRTC hello-world:

  • Two tabs join the same signaling room.
  • One tab creates a WebRTC offer.
  • The other tab creates an answer.
  • ICE candidates are exchanged.
  • A DataChannel opens.
  • The sender sends a text message.
  • The receiver displays it.

Do not begin compression, resume, or WASM work before this milestone is working.

Security expectations

Before a public alpha, the project should have:

  • A written threat model.
  • Clear privacy claims.
  • Temporary room expiration.
  • Temporary TURN credentials.
  • Input validation on signaling and protocol messages.
  • Unique nonces for encrypted blocks.
  • Manifest authentication.
  • Final file verification.
  • Wrong-key and tampered-frame tests.

Security details live in docs/security.md.

License

The project is licensed under the MIT license.

About

Riftsend is a browser-based end-to-end encrypted peer-to-peer file transfer app for sending huge files directly between devices, with resumable transfers and optional encrypted relay fallback.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages