DEV Community

Ondrej Machala
Ondrej Machala

Posted on

Annotate Your Screenshots Without Photoshop

I was putting together docs for a feature last week. Screenshot looked good, but the button I was documenting was buried in a busy toolbar. Without an arrow pointing at it, the screenshot was useless.

So I opened Figma. Drew an arrow. Exported. Realized the arrow was slightly off. Re-opened Figma. Fixed it. Re-exported. Committed.

Next sprint, the UI changed. Screenshot was stale. Had to redo the whole thing - including that damn arrow.

There has to be a better way.

Screenshots That Annotate Themselves

Heroshot has a visual editor built in. You pick what to screenshot, then draw annotations - arrows, rectangles, ellipses - right there on the page. When you regenerate screenshots, the annotations come with them.

Here is how it works:

One command to set it up:

npx heroshot config
Enter fullscreen mode Exit fullscreen mode

A browser opens. That's your visual editor.

Pick What to Capture

Click the crosshair icon, hover over any element, click. Done - you just defined a screenshot. No CSS selectors to write. Heroshot figures it out.

Want just a card? Click the card. Want the whole nav? Click the nav. The sidebar shows everything you've picked.

Now Draw On It

This is the part I actually got excited about. Select an annotation tool from the toolbar:

  • Arrow - point at the thing that matters
  • Rectangle - highlight a section or group
  • Ellipse - circle something important

Draw directly on the screenshot preview. Adjust the color, stroke width, opacity. The annotations are saved in your config and redrawn every time you regenerate.

No Figma. No Photoshop. No re-exporting when the UI changes.

Edit Text Too

Say your app shows real user data - emails, names, timestamps. You don't want that in your docs.

Click any text element and change it:

{
  "textOverrides": {
    ".user-name": "Sarah Chen",
    ".email": "sarah@example.com",
    ".timestamp": "2 hours ago"
  }
}
Enter fullscreen mode Exit fullscreen mode

Or do it visually - click the text tool, click the element, type the replacement. Clean, professional screenshots with realistic-but-safe data.

The Config It Generates

All of this - the element selection, padding, annotations, text overrides - ends up 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" }
        }
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

You never have to write this by hand. The visual editor generates it. But it's just JSON - you can tweak it if you want.

Regenerate Anytime

UI changed? New styles? Just:

npx heroshot
Enter fullscreen mode Exit fullscreen mode

Headless. No browser opens. Every screenshot regenerates with its annotations intact. The arrow still points at the right button, even if that button moved 20 pixels to the left.

Light mode AND dark mode? Both captured automatically. One config entry, two annotated screenshots.

What Else It Does

Since we're here:

  • Multiple viewports - desktop, tablet, mobile from one config
  • Actions before capture - click buttons, fill forms, dismiss cookie banners, open dropdowns
  • Session persistence - log in once, capture headlessly forever
  • Border radius and styling - rounded corners, borders, background fills
  • Hide elements - remove chat widgets, dev toolbars, anything distracting
  • CI/CD ready - runs headlessly in GitHub Actions, no display needed

Try It

npx heroshot config
Enter fullscreen mode Exit fullscreen mode

Pick some elements. Draw some arrows. Close the browser. Check the heroshots/ folder.

That's it. Your screenshots now have annotations that survive redesigns.


Heroshot is free and open source. Star it on GitHub if this saved you a trip to Figma.

Top comments (0)