I’ve been hooking together a few recent browser features in an effort to build something like the web on the web itself. Consider two people, a “host” (like a server on the web) and a “guest” (like a client on the web). This project, which I’ve been calling “potluck,” would let the host serve pages to the guest.

Here’s how I’ve tried to do that. The host opens a special page that houses the logic of how to serve a website. The host’s page sets up a service worker and a push subscription for the worker.

Push is a relatively new feature, so I’ll describe it. To create a push subscription, the browser registers with a service that’ll take care of receiving messages and delivering them to the browser. Currently, browser vendors provide these services for their own browsers. Mozilla runs one for Firefox, for example. This service provides the registrant with a URL where one can submit message to be pushed to the browser, which will give the message to the service worker. When a web app creates a push subscription, it receives this URL.

The host’s page displays this URL to the host, and the host can communicate this to the guest out of band. One issue with this project right now is that the URL has to stay the same for this project to be useful. The actual API has this one event that it dispatches when the push service ends the subscription or needs to change its URL, but I don’t currently handle that. Under the condition that the URL remains the same, then after the guest receives this URL, he can use it to communicate with the host at any time.

The guest opens another special page, which he provides with the host’s URL. The guest’s page can then make requests to the URL to send messages to the host’s service worker. In order to allow the host to send messages back to the guest, the guest’s page also sets up a service worker and a push subscription for its worker, and it sends an initial message to the host including the guest’s push subscription’s URL.

Now there’s bi-directional communication between the host and guest. You’re only supposed to send small messages through the push API. In this project, I use this channel to exchange a couple of signalling messages to establish a WebRTC connection.

The guest’s service worker also handles fetch events. When the guest accesses a URL in the scope of its service worker, the guest’s service worker marshals the request and sends it over the WebRTC connection to the host. The host unmarshals the request, runs it through the website logic to get a response, marshals the response, and sends it back to the guest. The guest unmarshals the response and the service worker gives it to the browser as a response.


This demo is built for Firefox. And it didn’t work for a lot of people that tried it.

Hello world host page

The host would go to that page, and allow notifications. A big long URL will appear in the “Connect link” section. That link goes to the guest page, and it has a parameter that conveys the host’s push URL. The host would send that link to the guest out of band.

The guest would click the connect link, then a “Connect” button on the page. Oh, and the guest would also allow notifications. Then, if everything works, the guest’s page should say “Connected”—and often, not everything works. Then, the guest would click the link in the “Site access” section to load a page from the host.

In this simple demo, the server responds with a host-specified message and also echoes the requested URL.

Another demo

Guestbook host page

This one demonstrates forms, routing, databases, and redirecting. I feel like it would be more fun with E4X though.

Don’t be confused

Don’t confuse this project with Mozilla Flyweb or Viral.js. Maybe think a little about Opera Unite though. No, maybe not that either.

Also, these demos are static files. But they use push servers. They also use ICE servers for WebRTC.

My last post was about either How to file a bug about GitHub itself or Hunk editing in git checkout –patch. Find out which.