---
title: "On self-updating screenshots"
date: 2026-05-08
tags: post
---

[Nick](https://www.nickbaum.com/) sent me [a great post from one of the engineers at Goodenough](https://interblah.net/self-updating-screenshots), the fine folks behind Jelly, on the topic of self-updating screenshots. It is near and dear to my heart: their approach, which uses Puppeteer to programmatically generate screenshots on every deploy, is spiritually adjacent to my own galaxy-brained approach of [[iframe-docs|just using iframes pointed at a live demo site]] to achieve the same end. Both are gambits to solve the same problem — the pernicious drift between docs and product — and both, in their own way, work.

So I figured I'd use this as a launching pad to talk about how our approach has aged, almost a year on. I'll riff across four dimensions:

1. **Performance.** Puppeteer wins this one, bar none. Once you've captured the images, they are in fact just images — none of the incumbent burden of loading one or multiple iframes and ticking through their lifecycle. We've mitigated this somewhat with lazy loading, but there's no world in which a static asset loses to a live frame on this axis.

2. **Stability.** I suspect, especially with the rise of LLM-based tooling, I need to update my priors here, because I still have a voice in my head biased against Puppeteer and its kin — especially in CI settings — on the grounds that they're flaky and persnickety. Conversely, our iframes have now aged to the point where we're starting to see some of the annoying cascading effects of the actual site changing out from under them: selectors disappearing, paywalls getting inserted where they weren't before. In an unfortunate bit of irony, this is not dissimilar from the original problem we were trying to solve, where the pernicious part of documentation drift is *not even knowing the drift has occurred.*

3. **Syntax and tooling.** Both approaches are basically the same here. The whole thing hinges on it being easy and ergonomic to add arbitrary images or iframes, and we've each landed in roughly the same place.

4. **End-user experience.** Both pretty solid here, modulo the aforementioned performance gap. For Jelly, the platonic ideal is *no perceptible difference* from a more conventional, manually-captured screenshot. Our aims are a little higher — but, if I'm being honest, we haven't really taken advantage of *perverting* iframes to our own ends in the way I'd hoped. The dynamic highlighting work scratches the surface; the much more interesting stuff (interactive walkthroughs, click-through tutorials, letting a user actually poke at the demo without leaving the page) remains theoretical. That's probably worth taking another look at the next time we want to invest some cycles in the docs.

---

All of which is to say: I'm still pretty married to our iframe approach. It hasn't been entirely smooth sailing, but it hasn't let us down either, and it's not a decision I regret. That being said! The above post inspired me to really try and spend some time revisiting Puppeteer without the baggage of the past — because the version of Puppeteer in my head is a 2021 vintage, and the world has changed quite a bit since then.
