← All articles

P2P Surfaces: Desktop and Browser

Part 7 of the [VIMS Blog Network](00-vims-convergence-point). Your data lives on your devices, replicated across peers you trust, no central server required.

Part 7 of the VIMS Blog Network. Your data lives on your devices, replicated across peers you trust, no central server required.

The Central Server Problem

Most collaboration tools share the same architecture: a central server stores your data, and every client connects to it. The server is the source of truth. If the server goes down, collaboration stops. If the server is breached, your data is exposed. If the server's pricing changes, you pay or you leave.

This model has a fundamental problem for agent systems: agents need to collaborate, but agents run on your hardware, not on the collaboration provider's server. An agent that needs to share a file with another agent should not need to upload it to a third-party service first.

VIMS takes a peer-to-peer approach. Surfaces (Team, Chat, Drive, Database, KB, Meeting, Schedule) sync directly between peers. No central server. No intermediary. Your data lives on your devices and is replicated to peers you choose to share with.

The Three-Layer Substrate

VIMS P2P is built on three layers:

1. Canonical Topic Naming

Every P2P surface has a canonical topic name: a deterministic identifier derived from a cryptographic key. Two peers that know the same topic name can find each other and replicate state. Topic names are not human-readable strings; they are derived from the swarm key, which is derived from the shared resource key.

This means there is no central registry of topics. No directory service. No DNS. If you have the key, you can find the peers. If you do not have the key, you cannot even know the topic exists.

2. Durability via CRDT Replication and Local Replicas

P2P systems have a well-known problem: when all peers go offline, the data is gone. VIMS solves this with two mechanisms:

  • Live CRDT replication over Gun: Surfaces that share mutable state (the chat event cache, the team room store, rooms and drive metadata) sync through Gun, a CRDT graph layer. Every mutation propagates to connected peers in real time, and CRDT merge rules make concurrent writes converge without coordination.
  • Persistent local replicas: Every peer holds the state locally: browsers in Gun's IndexedDB storage stack, desktops on disk. When a peer comes back online, it syncs forward from its local replica. There is no external snapshot store: the data lives on the peers, and durability comes from how many peers hold it.

The hosted Gun relay (swarm.vims.com/gun) is a rendezvous and cache, not a source of truth. Everything it holds is either a signed Nostr event (verified by readers, so the relay cannot forge content) or CRDT state that connected clients also hold. Wiping the relay's disk loses nothing a returning client cannot re-supply.

This gives P2P its durability without the central server: as long as any peer's replica survives, the room survives.

3. Transport via the Sidecars

Two sidecar processes carry the transport layer, each solving a different browser limitation.

The hyperswarm bridge owns one Hyperswarm DHT identity per VIMS host and multiplexes channels for every local consumer: the daemon, Electron, and in-shell browser tabs over its WebSocket relay. It manages Hyperswarm connections, Hypercore replication streams, and an optional WebRTC bridge that lets browsers exchange bytes directly with native peers over an RTCDataChannel. It is the bridge between the native P2P stack (which speaks the Hyperswarm DHT protocol) and the browser (which cannot open raw TCP/UDP sockets).

The Gun relay is the always-on rendezvous for the CRDT layer. Browsers cannot accept incoming connections, so browser-to-browser Gun sync needs one reachable peer both sides can dial; the hosted relay is that peer, and desktops run their own: in swarm mode it joins the DHT directly, so the hosted relay drops out of the path entirely.

Connectivity Modes

VIMS supports three connectivity modes, each addressing a different deployment scenario:

Desktop ↔ Desktop

Two VIMS desktop instances connect directly over Hyperswarm. The Hyperswarm DHT handles peer discovery: each peer announces itself on the DHT under the topic hash, and peers find each other by querying the same hash. Once connected, Hypercore replication streams handle state synchronization.

This is the native P2P path: no relay, no intermediary, no sidecar needed. Two laptops on different networks can find each other, connect, and sync a team room in seconds.

Desktop ↔ Browser

A browser tab cannot open raw TCP/UDP sockets. It cannot participate in the Hyperswarm DHT directly. So VIMS uses a sidecar WebSocket relay: the browser tab connects to the sidecar via WebSocket, and the sidecar handles the Hyperswarm connection on the browser's behalf.

The sidecar runs on a desktop instance (or a public VIMS ingress server). The browser tab sends mutations to the sidecar, which propagates them to the swarm. Incoming mutations from the swarm are relayed to the browser via WebSocket.

The sidecar is a transport relay, not a data store: it does not persist data, it forwards it. The data lives on the peers, not on the sidecar.

Browser ↔ Browser

Two browser tabs in different locations cannot connect directly; they need a signaling layer for WebRTC. VIMS uses the sidecar for signaling: each browser tab connects to a sidecar, the sidecars exchange WebRTC offer/answer messages through the DHT, and the browsers establish a direct WebRTC data channel.

Once the WebRTC connection is established, data flows directly between browsers; the sidecar is only involved in the initial signaling handshake. This is a true peer-to-peer connection between two browser tabs, mediated only for the initial connection setup. Shared CRDT state between the two tabs, meanwhile, syncs over Gun through the relay; on desktops running their own relay in swarm mode, through the DHT instead.

The Six P2P Primitives

VIMS exposes six P2P surfaces, each building on the same substrate:

  1. Discover: peer discovery and presence. Who is online, who is idle, who is offline. Last-seen timestamps. This is the foundation; every other primitive uses Discover to find peers.
  2. Database: SQL mirroring over P2P. Share a local database replica with peers. Every peer gets a local SQLite copy that syncs on changes.
  3. KB: knowledge base replication. Share a KB with peers. Documents, vector indices, and search results all sync over the swarm.
  4. Drive: file storage and sharing. Upload files to a shared drive; peers replicate them locally. Hyperdrive handles the file transfer: chunked, deduplicated, and resumable.
  5. Meeting: real-time voice and video. WebRTC mesh for media, Hyperswarm for signaling, HyperDHT for presence. Agents join as synthetic peers with their own audio stream.
  6. Teams: the composition primitive. A Team wraps the other five into one identity-rooted unit with roster management, RBAC, and shared component keys. (Blog 11: Flow and Teams)

The Shared Package Pipeline

VIMS surfaces are built as transport-free packages. This is a critical architectural decision:

  • Desktop has the daemon, so it has full P2P capability: Hyperswarm, Hypercore, HyperDHT, WebRTC.
  • Browser cannot run the native P2P stack: no raw sockets, no DHT participation.
  • The package contains the surface logic (UI, state management, business rules) with no transport code. Transport is injected as a capability: the desktop injects native Hyperswarm transport; the browser injects sidecar WebSocket transport.

This means desktop and browser consume the same code. There is no "desktop team surface" and "browser team surface"; there is one team surface package, consumed by both. When a feature is built, it works everywhere. When a bug is fixed, it is fixed everywhere.

This is a correctness invariant. If desktop and browser had separate implementations, they would diverge: different features, different bugs, different data models. The shared package pipeline prevents this by making one implementation canonical. (Blog 12: SDK, Coder, and Terminal)

Identity and Authentication

P2P without identity is anonymous, and anonymous peers cannot be trusted. VIMS authenticates peers using Nostr keys. Every peer has a Nostr keypair; the public key is the peer's identity on the swarm. When a peer connects, it signs a challenge with its private key; the recipient verifies the signature against the known public key.

For agents, the Nostr key is derived from the agent's NFT identity. An agent's peer ID on the swarm is its Nostr npub: the same identifier that appears on the marketplace, in team rosters, and in the audit trail. This means an agent's P2P identity is consistent across all surfaces. (Blog 08: Agent Identity)

Scale Considerations

VIMS P2P is designed for real-world scale:

  • Millions of topics: The DHT handles topic discovery at scale. Topic hashes are uniformly distributed across the keyspace, so topic lookup is O(log n) regardless of how many topics exist.
  • Hundreds to thousands of peers per room: WebRTC mesh handles small rooms (up to ~20 peers) with full mesh. For larger rooms, VIMS uses selective forwarding: a subset of peers act as relays, reducing the per-peer connection count.
  • Local desktop clients are ephemeral edge peers: They join when online, leave when offline. Public VIMS services provide always-on ingress and discovery: they are infrastructure, not data stores. If all desktop clients go offline, the public ingress keeps the swarm discoverable; when peers return, they rejoin and resume replication from their persistent local replicas.

The P2P Contract

P2P in VIMS is a contract:

  1. No central server. Data lives on peers. The swarm handles discovery and replication.
  2. Desktop is canonical for features. The daemon has more capability than the browser. The shared package is canonical for code. Both consume the same implementation.
  3. Browser is a first-class peer. Through the sidecar relay, browser tabs participate in the same swarm as desktop instances.
  4. Identity is consistent. Nostr keys authenticate peers. Agent NFTs render avatars in rooms. The same identity works everywhere.
  5. Durability is replication. Live Gun CRDT sync for shared surface state, Hypercore replication for the desktop swarm, plus persistent local replicas on every peer. Data survives peer churn as long as any peer's replica survives.

Previous: MCP Connectors Next: Voice and Meeting Agents: Whisper to Room