Treat Demos Like Unit Tests

We automate tests, builds and deployments. So why are screenshots and GIFs still manual?

We automate tests, builds and deployments. So why are screenshots still manual?

Every software project eventually reaches the same point. The feature is finished. Then comes the ritual:

  • Open the app
  • Resize the browser to whatever the Chrome Store spec says this year
  • Navigate to the right page
  • Take a screenshot
  • Record a GIF
  • Crop it
  • Compress it
  • Upload it to your landing page
  • Update your README
  • Replace your Chrome Store screenshots
  • Repeat after every release

Somewhere around step four you’ve probably checked out. I don’t blame you. I’ve started wondering why we accept this as normal.

The boring parts are already automated

Modern software projects automate unit tests, integration tests, linting, formatting, type checking, builds, deployments, changelogs and releases. We’ve automated most of the tedious parts of shipping. Yet the thing users actually see is often still created by hand.

It feels strange. Imagine if every release required manually recompiling your application. That’s effectively what we’re doing with screenshots.

Screenshots are build artifacts

I’ve started treating screenshots, GIFs and demo videos the same way I treat compiled output. Not marketing collateral you refresh when you remember. Build artifacts.

Instead of this…

pnpm test
pnpm build

…my ideal project looks more like this.

pnpm test
pnpm build
pnpm demo

That final command generates everything.

artifacts/
├── hero.png
├── social-card.png
├── chrome-store-1.png
├── chrome-store-2.png
├── onboarding.gif
├── demo.mp4
└── readme.gif

Nothing is created by hand. Everything is reproducible. At least in theory.

You probably already have the robot

This isn’t magic. Most of the tooling already exists, and if you’re writing browser tests you may already be paying for half of it.

If you’re already using Playwright, you already have something that knows how to click through your app. Instead of stopping after the assertions, keep going: navigate the happy path, capture screenshots, record video. The same script that proves the feature works can demonstrate it. Playwright can record sessions too. The test run leaves a video file on disk. Most teams throw that away. Keep it, trim it, ship it.

Need a GIF from the recording?

demo.mp4

 onboarding.gif

One ffmpeg command. No screen recorder, no timeline editor, no export settings to remember. I haven’t opened Premiere for a README GIF in months, and I’m not sad about it.

Need rounded corners, drop shadows, device frames, captions? Sharp and ImageMagick can generate those in the pipeline. No Figma file required.

The other big win is seeded demo data. Realistic names, sensible timestamps, meaningful content, dashboards that don’t look empty. No more “John Doe”. No more “Lorem ipsum”. No more realising halfway through that you’re screenshotting your own Gmail because you forgot to create a demo user.

What still breaks

I should be honest: this is not set-and-forget.

Demo scripts break when you rename a button. Someone still has to decide what the happy path is. Trimming a forty-second recording down to something that reads in a README is still fiddly. Seeded data takes setup. Flaky selectors are flaky selectors, whether they’re in a test or a demo.

But it’s fiddly once in code, not every release by hand. That’s the trade.

Consistency beats time saved

The obvious benefit is saving time. The bigger win is consistency.

Every screenshot uses the same browser size, spacing, colour theme, data and window chrome. Your documentation, landing page and store listing match the current version of the product. You stop shipping screenshots from three versions ago.

Marketing stops falling behind

One thing I’ve noticed with side projects is that marketing slowly drifts away from reality. You tweak the UI but the screenshots don’t get updated. You rename a feature but the GIF still shows the old interface. Eventually your website becomes a historical document, and the README animation is basically archaeology.

Automation fixes that. Whenever the UI changes, the demo assets regenerate alongside the build. If something looks wrong, you notice immediately.

It fits naturally into CI

Imagine every pull request producing:

  • ✅ Tests passed
  • ✅ Build passed
  • ✅ Documentation updated
  • ✅ Screenshots regenerated
  • ✅ README GIF refreshed
  • ✅ Social images rebuilt

The product isn’t just tested. It’s photographed.

My current rule

If I build a feature, I also build the script that demonstrates it. Same rule as unit tests: no feature ships without the thing that proves it works. Future me never has to remember how to recreate the perfect screenshot. The repository already knows.

Where this probably goes

Most repositories already have a /tests directory. I wouldn’t be surprised if /demo becomes normal too: one command that outputs landing page screenshots, README animations, store assets, social cards and release videos.

Not because marketing became more important. Because repetitive work became automatable, just like testing did.


The best automation isn’t the one that saves you the most time. It’s the one that removes a job you never wanted to do again.

Related