Annotate Your Screenshots Without Photoshop
Source: Dev.to
The Problem
When documenting a feature, a screenshot can look great—until the element you need to highlight is hidden in a busy toolbar. Without an arrow or other annotation, the screenshot isn’t useful.
Typical workflow:
- Open a design tool (e.g., Figma).
- Draw an arrow, export the image.
- Notice the arrow is slightly off → reopen, fix, re‑export.
- Commit the screenshot.
If the UI changes in the next sprint, the screenshot (and its arrow) become stale, forcing you to redo the whole process.
Introducing Heroshot
Heroshot provides a visual editor that lets you:
- Pick any element on a page to capture.
- Draw annotations (arrows, rectangles, ellipses) directly on the preview.
- Regenerate screenshots automatically, preserving all annotations.
No more external tools like Figma or Photoshop, and no re‑exporting when the UI changes.
Getting Started
npx heroshot config
One command opens a browser with the visual editor.
Selecting Elements
- Click the crosshair icon, hover over any element, and click to define a screenshot.
- No CSS selectors needed—Heroshot determines the element automatically.
Examples:
- Want just a card? Click the card.
- Want the whole navigation bar? Click the nav.
The sidebar lists everything you’ve selected.
Adding Annotations
Select a tool from the toolbar:
- Arrow – point at the important element.
- Rectangle – highlight a section or group.
- Ellipse – circle something important.
Draw directly on the screenshot preview, then adjust color, stroke width, and opacity. Annotations are saved in your configuration and redrawn on each regeneration.
Handling Sensitive Data
If your app displays real user data (emails, names, timestamps) that you don’t want in documentation, you can override the text:
{
"textOverrides": {
".user-name": "Sarah Chen",
".email": "sarah@example.com",
".timestamp": "2 hours ago"
}
}
Or do it visually: use the text tool, click the element, and type the replacement.
Configuration File
All selections, padding, annotations, and text overrides are stored in a simple JSON file:
{
"screenshots": [
{
"name": "Dashboard Settings",
"url": "https://myapp.com/settings",
"selector": ".settings-panel",
"padding": { "top": 20, "right": 20, "bottom": 20, "left": 20 },
"paddingFill": "solid",
"textOverrides": {
".user-email": "team@example.com"
},
"annotations": [
{
"type": "arrow",
"points": [200, 50, 300, 120],
"style": { "stroke": "#ff0000", "stroke-width": "3" }
}
]
}
]
}
You never have to write this manually; the visual editor generates it, but you can edit it if needed.
Regenerating Screenshots
When the UI changes, simply run:
npx heroshot
- Runs headlessly (no browser UI).
- Recreates every screenshot with annotations intact.
- Adjusts automatically if elements move (e.g., an arrow still points to a button that shifted 20 px).
Both light and dark modes are captured automatically—one config entry yields two annotated screenshots.
Advanced Features
- Multiple viewports – desktop, tablet, mobile from a single config.
- Pre‑capture actions – click buttons, fill forms, dismiss cookie banners, open dropdowns.
- Session persistence – log in once, then capture headlessly forever.
- Styling options – rounded corners, borders, background fills.
- Hide elements – remove chat widgets, dev toolbars, or any distracting UI.
- CI/CD ready – runs in GitHub Actions or other pipelines without a display.
Quick Recap
npx heroshot config # Open visual editor, pick elements, draw annotations
# Close the browser
# Check the heroshots/ folder for generated images
Your screenshots now include annotations that survive redesigns.
Open Source
Heroshot is free and open source. If it saved you a trip to Figma, consider starring the project on GitHub.