282 lines
17 KiB
HTML
282 lines
17 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" data-theme="dark">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
<meta name="theme-color" content="#0c0c10">
|
|
<script>
|
|
(function () {
|
|
try {
|
|
var t = localStorage.getItem('bridgeswarm.site.theme');
|
|
if (t !== 'light' && t !== 'dark') t = 'dark';
|
|
document.documentElement.setAttribute('data-theme', t);
|
|
var meta = document.querySelector('meta[name="theme-color"]');
|
|
if (meta) meta.setAttribute('content', t === 'light' ? '#2dd4bf' : '#0c0c10');
|
|
} catch (e) {
|
|
document.documentElement.setAttribute('data-theme', 'dark');
|
|
}
|
|
})();
|
|
</script>
|
|
|
|
<title>Use Cases — BridgeSwarm</title>
|
|
<meta name="description" content="Eight things you can build with BridgeSwarm: P2P chat rooms, collaborative apps, data sync, live media, self-hosted web apps, live topic domains, firewall-controlled rooms, and developer tooling — with concrete APIs and runnable examples.">
|
|
<meta name="author" content="HoneyPeer, LLC">
|
|
<link rel="canonical" href="https://bridgeswarm.honeypeer.com/use-cases/">
|
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@600;700;800&family=DM+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
|
|
<link rel="stylesheet" href="/src/styles/global.css">
|
|
<link rel="stylesheet" href="/src/styles/theme-light.css">
|
|
<link rel="stylesheet" href="/src/styles/docs.css">
|
|
<link rel="stylesheet" href="/src/styles/use-cases.css">
|
|
|
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicons/favicon-16x16.png">
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicons/favicon-32x32.png">
|
|
<link rel="icon" type="image/png" sizes="48x48" href="/assets/favicons/favicon-48x48.png">
|
|
<link rel="shortcut icon" href="/assets/favicons/favicon.ico">
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/favicons/apple-touch-icon.png">
|
|
<link rel="manifest" href="/assets/favicons/site.webmanifest">
|
|
<link rel="mask-icon" href="/assets/logo/bridgeswarm-wordmark.svg" color="#2dd4bf">
|
|
<meta name="msapplication-TileImage" content="/assets/favicons/mstile-150x150.png">
|
|
<meta name="msapplication-config" content="/assets/favicons/browserconfig.xml">
|
|
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:site_name" content="BridgeSwarm">
|
|
<meta property="og:title" content="Use Cases — BridgeSwarm">
|
|
<meta property="og:description" content="P2P chat, collaborative apps, data sync, live media, self-hosted apps, live topic domains, firewall-controlled rooms, and developer tooling — with the actual BridgeSwarm APIs behind each one.">
|
|
<meta property="og:url" content="https://bridgeswarm.honeypeer.com/use-cases/">
|
|
<meta property="og:image" content="https://bridgeswarm.honeypeer.com/assets/brand/og-image.png">
|
|
<meta name="twitter:card" content="summary_large_image">
|
|
<meta name="twitter:title" content="Use Cases — BridgeSwarm">
|
|
<meta name="twitter:description" content="P2P chat, collaborative apps, data sync, live media, self-hosted apps, live topic domains, firewall-controlled rooms, and developer tooling.">
|
|
<meta name="twitter:image" content="https://bridgeswarm.honeypeer.com/assets/brand/twitter-card.png">
|
|
|
|
<script type="application/ld+json">
|
|
{
|
|
"@context": "https://schema.org",
|
|
"@graph": [
|
|
{
|
|
"@type": "Organization",
|
|
"@id": "https://bridgeswarm.honeypeer.com/#organization",
|
|
"name": "HoneyPeer, LLC",
|
|
"url": "https://bridgeswarm.honeypeer.com/",
|
|
"logo": "https://bridgeswarm.honeypeer.com/assets/logo/bridgeswarm-icon-512.png",
|
|
"email": "[email protected]",
|
|
"sameAs": ["https://git.ssh.surf/snxraven/BridgeSwarm"]
|
|
},
|
|
{
|
|
"@type": "SoftwareApplication",
|
|
"@id": "https://bridgeswarm.honeypeer.com/#software",
|
|
"name": "BridgeSwarm",
|
|
"applicationCategory": "DeveloperApplication",
|
|
"operatingSystem": "macOS, Linux, Windows",
|
|
"url": "https://bridgeswarm.honeypeer.com/",
|
|
"publisher": { "@id": "https://bridgeswarm.honeypeer.com/#organization" },
|
|
"offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD" },
|
|
"license": "https://www.gnu.org/licenses/agpl-3.0.html",
|
|
"downloadUrl": "https://bridgeswarm.honeypeer.com/download",
|
|
"softwareVersion": "1.0.0",
|
|
"description": "Brings the Hyperswarm P2P stack into desktop browsers via a Bare native messaging host."
|
|
}
|
|
]
|
|
}
|
|
</script>
|
|
</head>
|
|
<body class="page-use-cases">
|
|
<div class="bg-mesh" aria-hidden="true"></div>
|
|
<div class="bg-grid" aria-hidden="true"></div>
|
|
|
|
<div data-nav data-prefix="../"></div>
|
|
|
|
<main id="main">
|
|
|
|
<header class="page-hero">
|
|
<div class="container">
|
|
<p class="section-label" style="justify-content:center;">Use cases</p>
|
|
<h1>What to build with BridgeSwarm</h1>
|
|
<p class="lead">Every example below runs on the bundled demos server. <a href="/download">Install BridgeSwarm</a>, enable <strong>Examples server</strong> in Settings, and open <a href="http://127.0.0.1:4173/" target="_blank" rel="noopener">http://127.0.0.1:4173/</a> in two tabs.</p>
|
|
</div>
|
|
</header>
|
|
|
|
<nav class="jump-nav reveal" aria-label="Jump to use case">
|
|
<div class="container jump-nav-inner">
|
|
<a href="#chat">Chat rooms</a>
|
|
<a href="#collab">Collaborative apps</a>
|
|
<a href="#sync">Data sync</a>
|
|
<a href="#live-media">Live media</a>
|
|
<a href="#self-hosted">Self-hosted apps</a>
|
|
<a href="#live-domains">Live topic domains</a>
|
|
<a href="#firewall">Firewall rooms</a>
|
|
<a href="#dev-tooling">Developer tooling</a>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="container usecase-list">
|
|
|
|
<section class="usecase reveal" id="chat" aria-labelledby="chat-title">
|
|
<div class="usecase-index">01</div>
|
|
<div class="usecase-body">
|
|
<h2 id="chat-title">P2P chat rooms</h2>
|
|
<p class="usecase-lede">A topic is a room. Everyone who joins the same topic string finds each other through Hyperswarm and exchanges messages over direct, Noise-encrypted connections — no chat server, no message broker, no accounts.</p>
|
|
<p>The <code>chat</code> example is a minimal single-file room: join a topic, broadcast text, render an inbox. <code>chat-advanced</code> builds rooms, presence, markdown rendering, emoji, and peer-to-peer file sharing on the same primitives.</p>
|
|
<pre><code>const swarm = new BridgeSwarm({ appName: 'chat-demo' });
|
|
await swarm.join('room:general');
|
|
swarm.on('connection', (conn, peerInfo) => {
|
|
conn.on('data', (data) => render(peerInfo.publicKey, data));
|
|
});
|
|
function broadcast(text) {
|
|
for (const conn of swarm.connections()) conn.write(text);
|
|
}</code></pre>
|
|
<div class="usecase-links">
|
|
<a class="btn btn-secondary" href="http://127.0.0.1:4173/chat/" target="_blank" rel="noopener">Try chat →</a>
|
|
<a class="btn btn-ghost" href="http://127.0.0.1:4173/chat-advanced/" target="_blank" rel="noopener">Try chat-advanced →</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="usecase reveal" id="collab" aria-labelledby="collab-title">
|
|
<div class="usecase-index">02</div>
|
|
<div class="usecase-body">
|
|
<h2 id="collab-title">Collaborative apps</h2>
|
|
<p class="usecase-lede">Anything that broadcasts small structured events to everyone in a session — cursors, strokes, edits — maps directly onto swarm connections. The <code>whiteboard</code> example is a shared canvas where every stroke is written to every connected peer as it happens.</p>
|
|
<p>For richer protocols than "write JSON, parse JSON," attach <a href="/learn/#protomux-hrpc">Protomux</a> to the connection and define named message channels instead of hand-rolling a dispatch table.</p>
|
|
<pre><code>swarm.on('connection', (conn) => {
|
|
conn.on('data', (buf) => applyRemoteStroke(JSON.parse(buf)));
|
|
});
|
|
canvas.addEventListener('pointermove', (e) => {
|
|
const stroke = strokeFrom(e);
|
|
for (const conn of swarm.connections()) conn.write(JSON.stringify(stroke));
|
|
});</code></pre>
|
|
<div class="usecase-links">
|
|
<a class="btn btn-secondary" href="http://127.0.0.1:4173/whiteboard/" target="_blank" rel="noopener">Try whiteboard →</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="usecase reveal" id="sync" aria-labelledby="sync-title">
|
|
<div class="usecase-index">03</div>
|
|
<div class="usecase-body">
|
|
<h2 id="sync-title">Data sync</h2>
|
|
<p class="usecase-lede">When you don't want to hand-roll message protocols at all, let the host replicate structured storage directly. <code>swarm.setAutoReplicate({ swarmId, enabled: true })</code> takes over every new connection on a swarm for Hypercore replication — those sockets stop forwarding raw data to the page and instead keep a Hypercore (or Hyperbee/Hyperdrive built on one) in sync across every peer automatically.</p>
|
|
<p>The <code>data-demo</code> example exercises Hyperbee, Hyperdrive, and Hyperdb directly through <code>BridgeSwarm.request</code>; <code>sync-demo</code> shows the auto-replicate path end to end.</p>
|
|
<pre><code>await BridgeSwarm.request('beePut', { key: 'title', value: 'Q3 plan' });
|
|
const doc = await BridgeSwarm.request('beeGet', { key: 'title' });
|
|
|
|
await swarm.setAutoReplicate({ enabled: true }); // new connections auto-sync</code></pre>
|
|
<div class="usecase-links">
|
|
<a class="btn btn-secondary" href="http://127.0.0.1:4173/data-demo/" target="_blank" rel="noopener">Try data-demo →</a>
|
|
<a class="btn btn-ghost" href="http://127.0.0.1:4173/sync-demo/" target="_blank" rel="noopener">Try sync-demo →</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="usecase reveal" id="live-media" aria-labelledby="live-media-title">
|
|
<div class="usecase-index">04</div>
|
|
<div class="usecase-body">
|
|
<h2 id="live-media-title">Live media</h2>
|
|
<p class="usecase-lede">The host's media capability pack wraps <code>bare-ffmpeg</code> for real encode work, including a <strong>live</strong> session mode: push captured frames in, get VP9/WebM segments out — to a Media Source Extensions player on the page, fanned out to swarm peers, or archived to disk, in any combination.</p>
|
|
<pre><code>const live = BridgeSwarm.media.liveSession(videoEl);
|
|
await live.start({ width: 640, height: 360, fps: 10, ingest: 'frames' });
|
|
await live.pushFrame(canvas);
|
|
await live.subscribe({ swarm: { connIds: [conn.connId] } }); // fan out to a peer
|
|
await live.stop();</code></pre>
|
|
<p>See <code>live-encode</code> for the host-encode → MSE pipeline, <code>media-demo</code> for batch probe/transform/transcode, and <code>clip-studio</code> for nearline recording workflows.</p>
|
|
<div class="usecase-links">
|
|
<a class="btn btn-secondary" href="http://127.0.0.1:4173/live-encode/" target="_blank" rel="noopener">Try live-encode →</a>
|
|
<a class="btn btn-ghost" href="http://127.0.0.1:4173/media-demo/" target="_blank" rel="noopener">Try media-demo →</a>
|
|
<a class="btn btn-ghost" href="http://127.0.0.1:4173/clip-studio/" target="_blank" rel="noopener">Try clip-studio →</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="usecase reveal" id="self-hosted" aria-labelledby="self-hosted-title">
|
|
<div class="usecase-index">05</div>
|
|
<div class="usecase-body">
|
|
<h2 id="self-hosted-title">Self-hosted web apps</h2>
|
|
<p class="usecase-lede">The bundled demos server is itself proof of a pattern worth building on: the Bare host can run a small <code>bare-http1</code> static server on <code>127.0.0.1</code> and serve a full HTML/CSS/JS app with no cloud hosting step. Because the content script injects <code>window.BridgeSwarm</code> into pages served from real HTTP origins (not <code>file://</code>), an app served this way gets P2P networking for free — it's a normal page as far as the browser is concerned.</p>
|
|
<p>This is the same mechanism the extension itself uses: toggle <strong>Examples server</strong> in Settings and the host starts serving on <code>127.0.0.1:4173</code> with no separate deploy step.</p>
|
|
<pre><code>// extension -> host, on settings change
|
|
examplesServer.start({ host: '127.0.0.1', port: 4173 })
|
|
// host responds
|
|
{ running: true, url: 'http://127.0.0.1:4173/' }</code></pre>
|
|
<div class="usecase-links">
|
|
<a class="btn btn-secondary" href="http://127.0.0.1:4173/" target="_blank" rel="noopener">Open the examples server →</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="usecase reveal" id="live-domains" aria-labelledby="live-domains-title">
|
|
<div class="usecase-index">06</div>
|
|
<div class="usecase-body">
|
|
<h2 id="live-domains-title">Live topic domains</h2>
|
|
<p class="usecase-lede">A DNS name is a static pointer maintained by infrastructure you rent. A Hyperswarm <strong>topic</strong> behaves more like an address you dial directly — whoever is currently announcing it is reachable, for as long as they keep at least one connection to the DHT. Nothing to register, nothing to renew, no hosting bill if nobody's listening.</p>
|
|
<p>You can lean on this directly: derive a topic from a room name, an invite code, or a content hash, and treat "join this topic" as the entire addressing scheme for a feature. The <code>chat</code> and <code>whiteboard</code> examples both do exactly this — the topic string <em>is</em> the room.</p>
|
|
<pre><code>const topic = await sha256(`my-app:${roomSlug}`);
|
|
await swarm.join(topic); // this room now "exists" for as long as someone's in it</code></pre>
|
|
<div class="usecase-links">
|
|
<a class="btn btn-ghost" href="/learn/#topics">Read: Hyperswarm topics as rendezvous →</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="usecase reveal" id="firewall" aria-labelledby="firewall-title">
|
|
<div class="usecase-index">07</div>
|
|
<div class="usecase-body">
|
|
<h2 id="firewall-title">Firewall-controlled rooms</h2>
|
|
<p class="usecase-lede">Discovery is open by design — that's the point of a DHT — but connections don't have to be. <code>swarm.setFirewall({ mode, keys })</code> switches a swarm between <code>off</code>, <code>allowlist</code>, and <code>denylist</code> modes keyed on peer public keys, and <code>swarm.ban(publicKey)</code> / <code>peerInfo.ban()</code> drops a specific peer outright.</p>
|
|
<pre><code>await swarm.setFirewall({ mode: 'allowlist', keys: [trustedKeyHex] });
|
|
|
|
swarm.on('connection', (conn, peerInfo) => {
|
|
if (isSpamming(peerInfo)) peerInfo.ban();
|
|
});</code></pre>
|
|
<p>The <code>firewall-room</code> example wires this up as a live allowlist/denylist/ban UI you can test against a second tab.</p>
|
|
<div class="usecase-links">
|
|
<a class="btn btn-secondary" href="http://127.0.0.1:4173/firewall-room/" target="_blank" rel="noopener">Try firewall-room →</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="usecase reveal" id="dev-tooling" aria-labelledby="dev-tooling-title">
|
|
<div class="usecase-index">08</div>
|
|
<div class="usecase-body">
|
|
<h2 id="dev-tooling-title">Developer tooling</h2>
|
|
<p class="usecase-lede">Two building blocks for anyone shipping a protocol on top of BridgeSwarm rather than a demo app: <strong>Protomux</strong> for hand-designed message channels in the page, and <strong>HRPC</strong> for schema-defined, streaming RPC on the host.</p>
|
|
<pre><code>// HRPC: unary + streaming from the page
|
|
await BridgeSwarm.request('attachHrpc', { connId: conn.connId });
|
|
const pong = await swarm.hrpcCall(conn.connId, 'ping', { value: 'hi' });
|
|
await swarm.hrpcCall(conn.connId, 'fetchStream', { count: 3 }, {
|
|
onChunk: (c) => console.log(c),
|
|
});</code></pre>
|
|
<p><code>sdk-demo</code> exercises swarm lifecycle and raw Protomux; <code>hrpc-demo</code> covers unary calls and both streaming directions end to end.</p>
|
|
<div class="usecase-links">
|
|
<a class="btn btn-secondary" href="http://127.0.0.1:4173/sdk-demo/" target="_blank" rel="noopener">Try sdk-demo →</a>
|
|
<a class="btn btn-ghost" href="http://127.0.0.1:4173/hrpc-demo/" target="_blank" rel="noopener">Try hrpc-demo →</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
</div>
|
|
|
|
<section class="cta-band reveal">
|
|
<div class="container">
|
|
<div class="cta-card">
|
|
<h2>Pick one and go build it</h2>
|
|
<p class="lead">Every demo above is source-available in the repo's <code>examples/</code> directory as a starting point.</p>
|
|
<div class="cta-actions">
|
|
<a class="btn btn-primary btn-lg" href="/download">Install BridgeSwarm</a>
|
|
<a class="btn btn-ghost btn-lg" href="/learn/">Read the docs</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
</main>
|
|
|
|
<div data-footer data-prefix="../"></div>
|
|
|
|
<script type="module" src="/src/js/site.js"></script>
|
|
</body>
|
|
</html>
|