I see no reason not to open-source it but I haven't bothered to do so. Send me an email (in profile) and I'll see to it happening. (It is easy to write. All the complexity is dealing with gRPC's rather awkward support for node, opentracing, prometheus, and all that good stuff. If you don't use gRPC, opentracing, and prometheus... you can just cut-n-paste the example from their website. My only advice is to wait for DOMContentLoaded to trigger rendering, rather than the default functionality of waiting 500ms for all network actions to complete. Using DOMContentLoaded, it's about 300ms end-to-end to render a PDF. With the default behavior, it's more than 1 second.)
Before Puppeteer I tried to make wkhtmltopdf work... but it has a lot of interesting quirks. For example, the version on my Ubuntu workstation understands modern CSS like flexbox, but the version that I was able to get into a Docker container didn't. (That would be the "patched qt" version in Docker, versus the "unpatched qt" version on Ubuntu. Obviously I could just run the Ubuntu version in a Docker container, but at that point I decided it was probably not going to be The Solution That Lasts For A While and we would eventually run into some HTML/CSS feature that wkhtmltopdf didn't support, so I decided to suck it up and just run Chrome.)
The main reason I didn't consider Puppeteer immediately is that Chrome on my workstation always uses like 100 billion terabytes of RAM. In production, we use t3.medium machines with 4G of RAM. I was worried that it was going to be very bloated and not fit on those machines. I was pleasantly surprised to see that it only uses around 200MB of RAM when undergoing a stress test.
Consider a case where you have a bunch of apps that generate PDFs. There are two ways to structure the system; either every application bundles the PDF-rendering logic (i.e., a copy of Chrome and its dependencies) and needs to be provisioned to run it, or you have it as a standalone service that each application calls for its PDF rendering needs.
There are advantages in either approach. First consider the monolithic approach. Say the "foo" service finds some crazy edge case that causes your PDF renderer to use all the RAM on the machine it's running on. The foo service obviously goes down. But the bar service, that doesn't have data that triggers that edge case, remains up, because they are isolated.
If you have the PDF rendering functionality out in a microservice, then foo's bad behavior prevents bar from rendering PDFs, and both applications appear broken for anything that involves generating a PDF. But of course, only the PDF rendering functionality is affected. If foo is in a crash loop because its built-in PDF renderer is broken, it can't do anything. If it's just getting errors from the PDF service, everything else it does still works, so that might be better.
You also have to consider the maintenance costs. The PDF renderer has a 0 day security problem. How do you update it in all 100 of your applications? It's going to be a pain. But if it's all behind an RPC service, you just update that one service, and all the other apps are fixed. The downside, of course, is what if you want some experimental new feature only in one app's PDF renders, but not in the others? That is harder to do when you only have one version of the renderer deployed globally; if each app bundled their own, you could safely upgrade one app to the experimental version without affecting all the others.
So my TL;DR is: it's complicated. There is no one true answer, rather there are multiple solutions all with separate sets of tradeoffs. I generally prefer microservices because my development strategy is "fix a problem and forget it". It is easy to do the "forget it" part when new features can't interact with old features except through a battle-tested API. Your mileage may vary.