필사 모드: When Does a Code Screenshot in Your Docs Start Lying — Turning Images into Build Artifacts
English- What a screenshot in a six-month-old document is doing
- A screenshot is an artifact with no source
- What goshot does
- What changes the moment it becomes a command
- Terminal output has the same problem
- Redacting secrets is not a bonus feature
- Keeping the style configuration in the repository
- The smallest thing you could add this week
- Summary and sources
What a screenshot in a six-month-old document is doing
There is a pretty code screenshot planted in the middle of a guide. Dark background, rounded corners, three red-yellow-green dots at the top left. Someone captured it from their editor six months ago and pasted it in.
Since then a function has been renamed. An option has disappeared. The body text of the document was updated. The image was not. Now that page says the new name in the paragraph above and shows the old name in the image below. And a newcomer generally believes the image, because a picture looks more concrete than prose.
The problem is not that the image is wrong. It is that nobody can find out that it is wrong. A code block would have turned up in a search. An image does not.
A screenshot is an artifact with no source
Put the problem another way. That PNG file sitting in the documentation repository is an artifact. And there is no way in the repository to build it again. Which editor, which theme, which font size, which region was cropped — none of that is recorded.
We treat this situation as an obvious problem in other areas. Commit a build output to a repository without its source and review will call it out. Yet images somehow get an exemption, because we think of an image as decoration for the document rather than as code.
Apply a single standard and the work to be done becomes clear. Anything that cannot be rebuilt with one command does not belong in the repository. Images are no exception.
There is a prior question to ask first, though: does this code have to be an image at all? Most code inside documentation is better as a code block. It can be copied, it turns up in searches, screen readers read it, and it wraps to the width of the screen. The cases where an image is justified are narrow. When information that cannot be carried in text has to come along, such as highlight colors or editor markers. When it goes into a medium that cannot hold text, such as a presentation slide or a social card. And when terminal color and alignment are part of the explanation. If none of those three apply and you were using an image, going back to a code block comes before solving the regeneration problem.
What goshot does
goshot is a Go library and CLI that turns code and terminal output into images. The README introduces it as a tool similar to Carbon or Silicon. The difference is that it runs on the command line rather than as a web page, and for the argument of this post that difference is everything.
Writing down only what I confirmed in the feature list: syntax highlighting uses chroma and supports hundreds of themes, terminal output containing ANSI colors is rendered as-is, and for window chrome you can choose the macOS, Windows 11, GNOME, or KDE Breeze look. Backgrounds support solid colors, seven gradients, and images; output is PNG, JPEG, and BMP, and it can also emit to the clipboard and to standard output. And a feature that automatically redacts API keys, tokens, and passwords is on the list.
Basic usage looks like this.
# one file to an image
goshot main.go -o main.png
# take standard input, send to the clipboard
cat main.go | goshot -c
# specify theme, window shape, and background
goshot main.go -t catppuccin-mocha -C gnome -b '#1e1e2e'
# highlight only certain lines
goshot main.go --highlight-lines 10..14
Installation is go install github.com/watzon/goshot/cmd/goshot@latest if you have Go, and an AUR package for Arch and an Ubuntu PPA are documented too.
The structure when used as a library is worth a look as well. The README describes it as a small pipeline: render the content into an image, wrap that in window chrome, place it on a background. The three stages are independent concepts, so changing just one is easy. If you are building a documentation tool yourself, this separation alone is a design worth borrowing. When changing the theme, changing the window shape, and changing the padding do not touch one another, the place you have to edit for a later bulk style change collapses into one spot.
What changes the moment it becomes a command
It is not that goshot is a special tool. Once image generation becomes a command, three things follow.
First, updating the document and updating the image become the same job. When you fix the code and fix the docs, you run the image generation command one more time. The process of a human opening a capture tool, sizing a window, and cropping disappears.
Second, differences become visible. When an image is produced deterministically from a source, the image does not change when the code does not change. So the mere fact that an image file appeared in a changeset is itself a signal.
Third, consistency becomes a rule. Theme, font, and padding are written as arguments to a command, so you no longer get a mixture of screenshots taken with each team member's own editor theme.
Terminal output has the same problem
What goes stale more often in documentation is terminal output rather than code, because the output format of a command changes quietly when the tool version goes up. goshot provides a subcommand that runs a command and turns its output straight into an image.
# run a command and turn the output into an image
goshot exec -A -p -- go test ./...
# make the title bar color follow the content naturally
goshot exec -A -p --title-bar-color auto -- ls -la
What matters here is not that the image is pretty but that the output is what actually ran when the document was built. Output transcribed by hand diverges from the original as the transcriber deletes or tidies lines, and there is no way to verify that divergence later.
Redacting secrets is not a bonus feature
Of everything on the feature list, I think automatic redaction is worth the most in practice. What makes credential leakage through screenshots dangerous is not the leak itself but how hard it is to detect. A text key committed to a repository gets caught by a secret scanner. A key inside an image does not. It stays there until a human notices it with their eyes.
goshot advertises automatic redaction of API keys, tokens, and passwords, and lets you choose the redaction style as well.
goshot config.go --redact --redact-style blur
One thing has to be made clear, though. Automatic redaction is a device that reacts to known patterns, and the formats specific to an internal system may not be among those patterns. So this feature belongs as the first net, not the last line of defense. The real line of defense is not using an environment that contains genuine credentials when you build documentation.
Keeping the style configuration in the repository
goshot lets you put default values for frequently used flags in a configuration file. According to the README, you write flag names and values in a flat form in ~/.config/goshot/config.yaml, and a flag given on the command line always wins.
theme: catppuccin-mocha
chrome: mac
background: '#1e1e2e'
corner-radius: 12
If this file lives in a home directory, each person gets a different result. So for a repository that builds documentation, it is better to keep these values inside the project rather than in the home directory and pass them explicitly from a script. Then a style change comes up in code review, and you never wake up one day to find the background color of every document has changed.
The smallest thing you could add this week
The smallest form looks like this. Keep the code fragments that will become the sources of the images in their own files, and write one rule that builds images from those files.
# build docs/images/*.png from docs/snippets/*.go
SNIPPETS := $(wildcard docs/snippets/*.go)
IMAGES := $(patsubst docs/snippets/%.go,docs/images/%.png,$(SNIPPETS))
images: $(IMAGES)
docs/images/%.png: docs/snippets/%.go
goshot $< -o $@ -t catppuccin-mocha -C mac --redact
Set up this way, the code fragments become actual compilation targets, so when a snippet goes stale the build or the linter tells you first. The image follows afterwards. The point of this arrangement is that instead of solving the problem of stale images with images, it turns the problem back into one of stale source.
There is something to record honestly here. This Makefile is not the result of me installing goshot and actually running it. The goshot commands and flags were confirmed in the repository README, and the pattern rule part of the Makefile is ordinary make syntax. When you adopt it, please run it against one small snippet first.
Summary and sources
The point is not the name of a tool. It is that images going into documentation should be held to the same standard as any other artifact. Can it be rebuilt with a command? If it cannot, then someday that image will start saying something false without anyone knowing.
- The watzon/goshot repository — feature list, CLI examples, configuration file format, license. Everything written about goshot in this post was confirmed in this repository's README.
- Confirmed from repository metadata: the license is MIT, the primary language is Go, and the repository was created in November 2024. Please weigh adoption with the understanding that this is a project maintained by a single developer and not a tool backed by a large company.
- The CLI examples in this post are carried over from the README, and the Makefile example was not verified by running it.
현재 단락 (1/46)
There is a pretty code screenshot planted in the middle of a guide. Dark background, rounded corners...