BEAM

Browser-Enabled Asset Messenger is an ephemeral, browser-to-browser file sharing application. A sender selects one or more local files, opens a temporary workspace, and shares a four-character ID or QR link. Recipients use that workspace ID to request files directly from the sender’s open browser.

BEAM Application

BEAM does not upload file contents to an application database or object store. The selected File objects remain in the sender’s browser and are transmitted only when a connected recipient requests them.

Features

Privacy model

BEAM is designed around local custody:

  1. Selecting a file gives the page a browser File reference; it does not upload the file.
  2. The sender opens a PeerJS peer identified by the workspace ID.
  3. A public PeerJS signaling service helps the browsers discover each other and negotiate a WebRTC connection.
  4. File bytes travel over the resulting peer data connection in 64 KiB chunks.
  5. The recipient assembles those chunks into a browser Blob for preview or download.
  6. Closing the sender’s page destroys the peer and makes the workspace unavailable.

The signaling service is external infrastructure, but it coordinates the connection rather than acting as file storage. WebRTC normally uses encrypted transport. Depending on network conditions, WebRTC may require a relay; deployment-specific PeerJS/ICE configuration determines that behavior.

Important limitations

Implemented safeguards

Live workspace behaviour

Application flow

flowchart LR
    S[Sender browser] -->|Register workspace peer| P[PeerJS signaling service]
    R[Recipient browser] -->|Find workspace peer| P
    P -. Connection negotiation .-> S
    P -. Connection negotiation .-> R
    S -->|WebRTC data channel: metadata and file chunks| R
    S --- L[Local File objects]
    R --- B[Preview Blob or device download]
sequenceDiagram
    participant S as Sender browser
    participant P as Peer signaling
    participant R as Recipient browser
    S->>P: Register lvws-CODE
    R->>P: Connect to lvws-CODE
    P-->>S: Incoming peer connection
    P-->>R: Connection established
    R->>S: hello with optional password
    alt Password accepted
        S-->>R: manifest with file metadata
        R->>S: get with selected file ID
        S-->>R: file-start
        loop 64 KiB chunks
            S-->>R: ArrayBuffer chunk
        end
        S-->>R: file-end
        R->>R: Build Blob and preview or save
    else Password rejected
        S-->>R: denied with reason
    end

Technical design

Stack

Main modules

Module Responsibility
src/components/AppShell.tsx Shared navigation, unified homepage, focused-page layout, and BEAM brand statement
src/components/SharePanel.tsx Local file selection, workspace lifecycle, QR generation, settings, guests, and outgoing transfers
src/components/ReceivePanel.tsx Workspace connection, manifest display, incoming transfer state, previews, and downloads
src/components/FilePreviewModal.tsx Browser-native previews for supported file types
src/lib/peer-share.ts Workspace code generation, protocol types, chunk size, and transfer formatting helpers
src/lib/theme.tsx Theme state and browser persistence
src/routes/index.tsx Combined Share and Receive homepage
src/routes/share.tsx Focused sender page
src/routes/receive.tsx Focused recipient page and QR-link code handling

Wire protocol

Recipient-to-sender control messages:

Sender-to-recipient control messages:

The protocol also defines waiting and closed messages for future lifecycle handling. Binary payloads between file-start and file-end are ordered ArrayBuffer chunks. The sender applies basic backpressure by waiting when the data-channel buffer exceeds eight chunks.

Workspace lifecycle

stateDiagram-v2
    [*] --> Idle
    Idle --> Starting: Select files and open workspace
    Starting --> Live: Peer ID registered
    Starting --> Idle: Registration error
    Live --> Live: Recipient requests files
    Live --> Ended: Sender closes workspace
    Live --> Ended: Expiry reached
    Live --> Ended: Download limit reached
    Ended --> Starting: Open a new workspace

Local development

Requirements: a current Node.js runtime and npm or Bun.

git clone <repository-url>
cd <repository-directory>
npm install
npm run dev

The local site is served by Vite. Open the displayed URL in two browser windows or devices to exercise both sides of a transfer.

Commands

Command Purpose
npm run dev Start the development server
npm run build Create a production build
npm run build:dev Create a development-mode build
npm run lint Run ESLint checks
npm run format Format the project with Prettier

Testing a transfer

  1. Open / or /share in the sender browser.
  2. Add one or more files and optionally configure password, expiry, and download limit through the settings icon.
  3. Select Open workspace and copy the ID/link or scan its QR code.
  4. Open the link on another browser or enter the ID on / or /receive.
  5. Supply the password if configured, connect, then preview or download a file.
  6. Keep the sender page open until all transfers complete.

Troubleshooting

Deployment notes

Serve BEAM over HTTPS in production because browser peer connections, clipboard access, and related APIs have secure-context requirements. No application database is required for the current feature set. If self-hosting, review PeerJS signaling and ICE/TURN configuration for the network environments you need to support.