Skip to content
v2See what changed

Your visitors are your CDN

A service worker answers requests for your assets from this browser's cache, then from the other visitors on your site over WebRTC, and only then from your server. Every visitor who has a file can send it to the next.

npm install peer-cdn
sw.ts
const cache = new CachePlugin();
const peers = new DelegatePlugin();
const network = new NetworkPlugin();
// This browser's cache, then the other visitors,
// then your server, caching what comes back
new PeerCDN()
.GET('/assets', ordered,
cache.getMiddleware,
peers.getMiddleware,
network.getMiddleware)
.register();
  • 2.4 KBworker with the cache, the peers and the network, gzipped
  • 0WebRTC code in the worker: the pages hold the connections
  • 1Vite plugin to serve and build the worker
  • 3browser engines its tests connect real visitors in

Features

Routes in your worker

Send requests for a path through middleware, asked in order or all at once: the cache, the other visitors, the network, or your own.

Visitors share their cache

Each open page shares what its worker cached, and finds files among the other visitors for its worker, over peer-data data channels.

Careful with what it shares

Only same-origin 200 responses not marked private or no-store. Scripts and stylesheets come from a peer only when they match the request’s Subresource Integrity metadata.

The network as a fallback

What no cache or visitor has comes from your server. Requests you don’t route are left to the browser.

Vite plugin

peer-cdn/vite bundles your worker into one script for every browser, and runs the signaling server on Vite’s own server while you develop.

Small and typed

ES modules in strict TypeScript. The worker side has no dependencies; WebRTC stays in the pages.

Try it

Each visitor below has a cache of its own, as a visitor in another browser has. Load the pictures as Visitor 1 and they come from the server. Load them as Visitor 2 and they come from Visitor 1, over WebRTC. The visitors found each other through BroadcastChannel, with no signaling server.

Your server has sent 0 pictures.

Visitor 1

Looking for other visitors…

  • DunesNot loaded
  • TideNot loaded
  • OrbitNot loaded
  • MosaicNot loaded
  • BloomNot loaded
  • PeaksNot loaded

Visitor 2

Looking for other visitors…

  • DunesNot loaded
  • TideNot loaded
  • OrbitNot loaded
  • MosaicNot loaded
  • BloomNot loaded
  • PeaksNot loaded

Upgrading

The router, the strategies and the plugins keep their shape. Import them instead of loading a global, bundle the worker, and let PeerPlugin answer the worker by itself.

v1
self.importScripts('/peer-cdn/index.js');
const { CachePlugin, NetworkPlugin } = PeerCDN;
const { ordered } = PeerCDN.strategies;
const cachePlugin = new CachePlugin({ version: 1 });
const networkPlugin = new NetworkPlugin();
const cdn = new PeerCDN();
cdn.GET('/css/main.css', ordered,
cachePlugin.getMiddleware,
networkPlugin.getMiddleware);
cdn.register();
v2
import { CachePlugin, NetworkPlugin, PeerCDN, ordered } from 'peer-cdn';
const cache = new CachePlugin();
const network = new NetworkPlugin();
new PeerCDN()
.GET('/css', ordered,
cache.getMiddleware,
network.getMiddleware)
.register();

Share your assets between visitors

Add a worker, a line to each page and a signaling server. With Vite, the plugin sets up the worker and the server for you.