termshot: turn terminal output into a windowed screenshot
Creates screenshots based on terminal command output
At a glance
- What is it?
- termshot is a Go tool that runs a command in a pseudo terminal, reads the ANSI escape codes the command produced, and renders the result as an image that looks like a terminal window. Unlike web based screenshot services it does not apply syntax highlighting to pasted text, and it ships flags for wrapping, cropping sensitive output and writing raw output for scripts.
- Who is it for?
- termshot is worth installing if you publish terminal output, write documentation, or want to hand a colleague a picture of what a command actually printed rather than a copy of the text. It is the wrong tool if you need reproducible images from a build pipeline with colour disabled, and it is the wrong tool for commands that move the cursor around, since that is where the parsing is known to fail.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 38 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
It reads ANSI codes instead of guessing at colours
The tool reads the console output of a command and renders an output image that resembles a user interface window. The design decision that separates it from similar tools is stated in the readme. It is inspired by web based tools like carbon.now.sh and codekeep.io/screenshot, but unlike those, termshot does not blindly apply syntax highlighting to pasted text. Instead it reads the ANSI escape codes, the rich text logged by most command line tools, and uses them to generate a high-fidelity screenshot of the terminal output. That is a real difference in approach. A syntax highlighting service has to guess what a line of text means, while a program that honours the escape codes knows exactly which cells are which colour, which are bold, and which are underlined, because the original program said so. The result is closer to what the user saw than a reconstruction of it.
Prefix the command, and it writes out.png
The usage model is the same idea as time, watch or perf: you prefix the command you want to capture. The tool runs it in a pseudo terminal, and the result is an image file:
termshot ls -aThat produces a file called out.png in the current directory. The pseudo terminal is the mechanism, and it is why a program that thinks it is talking to a real terminal behaves the way it would in front of you, including colour output and progress bars. One wrinkle is worth knowing: if the command contains pipes there can still be ambiguity even with the -- separator, and in that case you wrap the command in double quotes.
termshot -- "ls -1 | grep go"The double quotes are what stop your own shell from interpreting the pipe before termshot ever sees it. Getting that wrong is the classic reason a piped command either fails or produces an empty screenshot.
The flags that shape the window
A generated window has a lot of adjustable geometry, and the flags are grouped by what they affect. --show-cmd, with the short form -c, includes the target command in the screenshot, which matters when the picture is going into documentation where the reader should see what was run. --columns, or -C, enforces that the screenshot is wrapped after the given number of columns, so you can keep a wide line from running off the edge of the image. --no-decoration removes the window decorations, meaning the minimise, maximise and close buttons, and --no-shadow removes the window shadow, both of which make the result look less like a mockup and more like a crop. --margin, or -m, adds space around the window, and --padding, or -p, adds space around the content inside the window, which is how you stop text from touching the border. The distinction between margin and padding is the distinction between the frame and the content, and having both means you can align the image with the surrounding page.
Naming the file, and hiding what should not be published
The output path is set with --filename, or -f, and it accepts an absolute path or a relative one, with relative paths resolved against the current working directory, defaulting to out.png.
termshot --filename screenshots/my-image.png -- "ls -a"There is also a --clipboard, or -b, which skips the file entirely and puts the image on the operating system clipboard, and the readme is careful to say that this flag only exists on some platforms and that you should check the tool's own help to see whether it is there. The flag I would point at first, though, is --edit, or -e. It opens the rich text output in the editor configured in $EDITOR, with vi as the fallback, so you can remove unwanted or sensitive output before the image is generated. A screenshot of a terminal session is a good way to leak a hostname, an internal path, an API key printed by accident or a colleague's name, and the edit step is the one control that addresses that at the source rather than after the fact.
Raw mode for scripts and pipelines
Two flags exist for the cases where a screenshot is not what you want. --raw-write takes a file argument and writes the command output into it as it is, with no screenshot created, and the --filename flag has no effect when it is used. --raw-read takes a file argument and reads the input from that file instead of running a command, and in that case no pseudo terminal is created at all, so the --show-cmd and --edit flags do nothing either. Together they make termshot usable in a pipeline: capture the coloured output to a file with one command, then render that file with another, which lets you keep the capture step and the render step separate. That separation is what you want in a script, where the command is run once and the image is regenerated whenever the surrounding text changes, and it is why the readme documents which flags stop working rather than leaving you to guess.
Several commands in one screenshot
Because the tool works through a pseudo terminal, it can host a whole session. You invoke a fully interactive shell, run several commands, and capture the entire output, and the screenshot is created once you terminate the shell.
termshot /bin/zshThat is the way to produce a single image of a sequence, which is far more useful in a tutorial than three separate pictures. The trade-off is that the capture ends when the shell exits, so the command has to end for the image to appear, and you have to remember that the file is written at the end rather than at the start. The readme also mentions that the tool can print its version, with the short flag -v, which is the quickest way to check which build you have when the output format changes between releases.
Where the rendering still breaks
The readme is direct about the limits, and the sentence is worth reading before you publish an image. This project is a work in progress. Although a lot of the ANSI sequences can be parsed, there are definitely commands in existence that create output that cannot be parsed correctly yet, and commands that reset the cursor position are known to create issues. Cursor movement is the hard case for any terminal renderer, because a full screen application redraws in place rather than printing lines, and a tool that only understands colours and line breaks will produce nonsense for those. The implementation is Go 1.25 with a dependency list that explains the design: creack/pty for the pseudo terminal, gonvenience/bunt for terminal colour handling, fogleman/gg for drawing, golang/freetype and gonvenience/font for the type, esimov/stackblur-go for the window shadow, spf13/cobra for the command line, and Ginkgo with Gomega for the tests, which the Makefile runs with the race detector and randomised suites. Releases are published through goreleaser as pre-compiled binaries for Darwin and Linux, and the licence is MIT.
Editorial conclusion
termshot is worth installing if you publish terminal output, write documentation, or want to hand a colleague a picture of what a command actually printed rather than a copy of the text. It is the wrong tool if you need reproducible images from a build pipeline with colour disabled, and it is the wrong tool for commands that move the cursor around, since that is where the parsing is known to fail. Before you use it in a README, run the command once and look at the image, because the tool itself says it is a work in progress and that some ANSI output still renders incorrectly.
Frequently asked questions
What is termshot?
termshot is a Go tool that runs a command in a pseudo terminal, reads the ANSI escape codes it produced, and renders an output image that looks like a terminal window. Unlike web based screenshot services it does not apply syntax highlighting to pasted text, so the colours are the ones the command actually emitted.
How do I install termshot?
On macOS or Linux, install it with Homebrew using brew install homeport/tap/termshot. Pre-compiled binaries for Darwin and Linux are also published on the project's releases page.
How do I screenshot a command that contains a pipe?
Wrap the command in double quotes after the separator, for example termshot -- "ls -1 | grep go". With pipes there can still be ambiguity even with the separator, and the quotes stop your shell from interpreting the pipe first.
Can I remove sensitive output before the screenshot is made?
Yes. The --edit flag, or -e, opens the rich text output in the editor configured in $EDITOR, using vi as a fallback, so you can strip unwanted or sensitive lines before the image is generated.
What do the raw flags do?
--raw-write writes the command output into the given file as it is and creates no screenshot, and --filename has no effect. --raw-read reads input from the given file instead of running a command, creates no pseudo terminal, and makes the --show-cmd and --edit flags do nothing.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/homeport-termshot)Was this useful?