There's no pen tool.
I found a bug, took a screenshot with my own tool, drew an arrow, placed some text. So far so good. But I wanted to circle this curved area freehand. I looked for a pen tool. It wasn't there.
I made this thing. And it doesn't have what I need.
Two months ago, I wrote about building a Skitch alternative in one day. That version had 5 tools: arrow, text, rectangle, mosaic, and numbered circles. "This is enough," I thought.
It wasn't. Using it every day revealed what was missing.
This is the story of growing from 5 tools to 9.
PureMark Annotate — Opens in your browser. No install, no login, nothing leaves your device.
annotate.puremark.app
What I Added
| Tool | Why I Needed It |
|---|---|
| Pen (freehand) | Rectangles can't outline curved shapes |
| Marker (highlight) | Needed semi-transparent emphasis without hiding text |
| Straight line | Less assertive than arrows for "from here to here" |
| Ellipse | Rectangles look awkward around non-rectangular targets |
Beyond tools, I fixed friction points I discovered through daily use:
| Feature | Before | After |
|---|---|---|
| Undo | None | 50-step history stack |
| Stroke size | Fixed | S / M / L |
| Text size | Fixed (24px) | S(18) / M(24) / L(36) |
| Export | 3x scale + PNG | 1x + JPEG 0.92 |
What Google Search Console Taught Me
I was checking GSC data when something caught my eye.
Annotate's impressions spiked one week. +450%. The search queries: "screenshot annotation tool free", "add arrow to screenshot", "image markup online".
These weren't developers.
I'd assumed my tool was for developers because I'm a developer. But GSC said otherwise. People who annotate screenshots aren't just engineers — they're PMs filing bug reports, IT staff writing manuals, directors giving design feedback.
That's when I pivoted. I changed meta descriptions to Japanese (85% of users were from Japan, but descriptions were in English). I changed applicationCategory from DeveloperApplication to MultimediaApplication. Added JSON-LD structured data. Basic stuff I'd completely overlooked.
iPhone Images Went from 5MB to 800KB
One day I saved an annotated image on my iPhone. 5.2MB. Too heavy to paste into chat.
The culprit was 3x export scaling. I'd been exporting at triple resolution for Retina sharpness, but 1x was perfectly fine in practice. Switching from PNG to JPEG (quality: 0.92) sealed the deal.
// Before: 3x PNG — 5.2MB
const scale = 3;
canvas.toBlob(blob => { /* ... */ }, 'image/png');
// After: 1x JPEG — 0.8MB
const scale = 1;
canvas.toBlob(blob => { /* ... */ }, 'image/jpeg', 0.92);
85% reduction in file size. The quality difference? You'd have to put them side by side to notice.
Users don't want "beautiful images." They want images they can send right now.
Works great on mobile too. iPhone, Android — just a browser.
annotate.puremark.app
Android Camera OOM'd
Testing on a Redmi 12 5G (4GB RAM), I took a photo and switched back to the browser. White screen. OOM — out of memory.
Using capture="environment" triggers the system camera, which generates 12-50 megapixel images. The browser tries to decode at full size and crashes before reaching any resize logic.
The fix: implement an in-app camera with getUserMedia and cap resolution at 1920x1440.
const stream = await navigator.mediaDevices.getUserMedia({
video: {
facingMode: 'environment',
width: { max: 1920 },
height: { max: 1440 },
}
});
But that alone didn't work. My Cloudflare _headers had Permissions-Policy: camera=() — blocking camera API for all origins. The browser silently denied access without even showing a permission dialog. Changed to camera=(self) and it worked.
Security headers protect you when configured correctly. When they're not, they become invisible bugs.
Undo Almost Killed It
Adding drawing tools meant I needed Undo. You draw a pen stroke, realize it's wrong, and want to go back.
I wrote about the implementation details in a separate article. The short version: Canvas API has no concept of "remove an element" like the DOM. Every undo clears the canvas and redraws all annotations from scratch. 50-step history stack — undo removes the last item and redraws, redo adds it back.
Sounds simple, but mosaic has a different draw order (it reads pixels from the original image), so rendering splits into 3 passes: Pass 1: Mosaic, Pass 2: Highlights, Pass 3: Everything else. Get the order wrong and mosaic overlaps your annotations.
2 Months in Numbers
| Metric | February (launch) | April (now) |
|---|---|---|
| Tools | 5 | 9 |
| MAU | 0 | 328 |
| Zenn articles | 1 | 17 |
| Chrome extension installs | — | 52 |
| GSC impressions (Annotate) | 0 | peak 80/week |
MAU is 328. The Gate 1 target is 500 — I'm at 65%. Still a ways to go, but the tool feels like something I want to use now.
Cross-tool navigation rate (users who visit other PureMark tools) exceeded 20%. One in five people use the full suite, not just Annotate. That was a good number to see.
Beyond "There's No Pen"
Two months ago, I noticed there was no pen. Today, there is. And a marker, and ellipses, and Undo.
But I'll notice something else missing soon. Because I'm still the primary user.
The best part of building your own tool is that the distance from "this is missing" to "done" is zero. No tickets, no sprint planning. You notice it and you ship it. That's how 5 became 9. I don't know what 9 becomes next.
A tool that started with "just draw an arrow on a screenshot" isn't just about arrows anymore.
PureMark Annotate — Try it now in your browser
Top comments (0)