puppetromium

A stupidly simple web-browser based on Puppeteer

Usage no npm install needed!

<script type="module">
  import puppetromium from 'https://cdn.skypack.dev/puppetromium';
</script>

README

:tophat: puppetromium npm npm

puppetromium in action

A simple browser UI for puppeteer, built with no client-side JavaScript.

Puppetromium is a single file simple web-browser built on Puppeteer. If Chromium and Puppeteer had a love child, it would be this horrible. Probably.

Also, there is no (as in zero "0") client-side scripting (in this browser UI) of any kind. No JavaScript. No ActionScript. No Flash. This crazy-simple remote browser UI is built entirely with HTML and CSS.

How is this possible?

With the power ⚡ 💪, my friend, of the following ancient®️ techs©️ from ye olde webbe:

but why?

Mostly as an exercise. To see how simple I get a remote browser that is still minimally usable. But also as an example of why puppeteer is not a great fit for this. And a reminder why I created a whole other browser driving protocol atop the DevTools protocol for my custom remote isolated browser.

Also because I thought people will think a browser UI built with Puppeteer is cool, and it might encourage them to get into remote browsing, and custom browser UIs for cloud browsers, and hack on top of it. I wanted to release something with a very permissive license, that might spark people's imaginations about how they could use this kind of tech in their own project. I wanted something I could build in 1 day (and indeed, it took me around 6 hours). I wanted something where I wasn't restricted by the need to keep the license strict (e.g., AGPL-3.0), in order to preserve my business of selling corporate license exceptions and SaaS deployments.

I wanted to give people a way they could get their toes wet, without having to pay anything, and so they might build their own on top of it. Because the type of people who would probably find this useful to hack on, are not the type of people who want to pay for a corporate license.

so, how simple is it?

A single NodeJS file that serves everything, 350 source lines of code, 6 endpoints (5 GET, 1 POST), 1 export and 3 external imports (express, mjpeg-server, and of course puppeteer).

okay, but how you size the remote browser viewport to roughly match my screen without any client-side JavaScript, what crazy majyck is this?

With, my friend, the following ingenious idea:

/* code to set the viewport approx size without client side JS */
    // for all w and h combinations that are relevant
    `@media screen and (min-width: ${w}px) and (min-height: ${h}px) {
      body {
        background-image: url("/set-viewport-dimensions/width/${w}/height/${h}/set.png") 
      }
    }`

    app.get('/set-viewport-dimensions/width/:width/height/:height/set.png', async (req, res) => {
      const ua = req.headers['user-agent'];
      const isMobile = testMobile(ua);
      let {width,height} = req.params;

      width = parseFloat(width);
      height = parseFloat(height);
     
      await page.emulate({
        viewport: {
          width,
          height,
          isMobile
        },
        userAgent: ua
      });
    ...

How can I too?

Alternative install mantras:

$ npx puppetromium@latest 8080
# or
$ npm i -g puppetromium@latest
$ puppetromium 8080

Or:

$ npm i --save puppetromium

Then:

import {start} from 'puppetromium';
start({port:8080, url:'https://jspaint.app'});

Or:

$ git clone https://github.com/i5ik/puppetromium.git
$ cd puppetromium/
$ npm i 
$ npm start 8080

HELP! It broke

It's probably because of puppeteer dependencies. Make sure you have them all installed. I included a bunch of dependency scripts tailed to Debian (which may work on other Linuxes, but your mileage may encounter variability).