Examples must run; static screenshots drift from the implementation
Aliases: living example · executable snippet · screenshot drift
What it is
A runnable example shares a build artefact with the component: the same entry, the same version, one click executing against the current implementation. A static screenshot is pixels left by some past commit, unbound from source, and it will not fail itself when the implementation moves. Examples need to run because they carry both “how it looks” and “is this still the right way to write it”; a screenshot carries only the former, and even that becomes a lie after the next release.
Runnable is not “there is a sample in the repo”. If that sample cannot be built, clicked, and asserted on a docs page or in a sandbox, it differs from a screenshot only by being prose that can also rot. The run is what turns the example from an illustration back into a live copy of the interface.
Why it happens
No compiler sits between a screenshot and the implementation. A prop is renamed, a default flips, a slot is restructured — the screenshot still shows the old frame, and readers write new code against the old frame. Staleness has no signal: no red build, no expired badge, only the next consumer hitting a prop that exists in the docs and not in the package.
A runnable example hangs on the same build graph. If the component’s tests fail, the example page fails; if the entry is deleted, the example’s import errors. Failure is pulled forward to before release. It can also be interacted with: keyboard, focus, and empty states are not something a picture can fake — they have to actually run. Screenshots are cheap in review; the cheapness is that they push “stay in sync with the implementation” onto someone in the future, who usually never arrives.
Where it stops holding
Print, slides, and design reviews with no runtime have only screenshots to put on the table; stamp the package version and commit on the image, and replace it with a runnable copy afterwards. Visual regression itself produces screenshots — those are assertion baselines, not usage to copy. When motion and pointer traces cannot be fully replayed on a docs page, a short video may cover the process, still sitting next to a runnable still endpoint. Examples that need live accounts or paid data will fail on public docs; ship a sanitised local fixture rather than falling back to a screenshot and stopping there.
Applying it
- Bind every usage block on a docs page to a buildable entry, run with the same tooling as component tests; a failed build is a failed doc.
- Do not let an unbound screenshot be the only example. Still frames that must appear get a package version in the filename or caption, and a link to the runnable copy.
- Reference example code from source files; do not hand-paste a parallel copy into the document.
- How to check: rename a public prop and run the docs build — every example still using the old name must go red. Hold a three-month-old screenshot against the current sandbox: pixels that still match while the code no longer runs are drift samples. Then walk keyboard and empty state in the example — paths drawn in the screenshot and absent at runtime are all lies.
Related
- Same group: R1.12.1 Guidance placed at the point of use is more likely to be read than a docs site · R1.12.3 Documentation ownership is bound to the component's change flow
- Adjacent: R1.04 Usage guidelines · R1.05 Versioning and migration
- Search terms:
runnable examples·living example·docs screenshot drift