Every screen tool that measures pixels ends at a human's eyeball: a ruler shows you a number, a screenshot app draws an arrow, a mouse tracker prints a position you copy by hand. pixelcoords starts from a different premise — the real consumer of a coordinate is a machine.
It freezes your screen so nothing moves while you measure, then lets you mark regions with real shapes — rectangles, ellipses, triangles, N-gons, freehand — rotated, labeled, and placed to the exact pixel with a loupe and arrow-key nudging. What you mark becomes data, not a picture: versioned JSON in physical pixels with per-monitor DPI scale, labeled crops and frame-sized cutouts, and ready-to-paste click code for your automation stack.
Then it answers the questions a machine actually asks about that data — each with an exit code and one JSON shape, so CI and computer-use agents can script them. Did this click land in the right region, for one point or a whole trajectory. Where do I click now, in the units my input API wants, on the display it's actually on. Wait until this dialog is back. Do these regions still look right. Where did this region move to when the UI drifted out from under my coordinates. Sessions reopen and edit like documents.
No account, no network, no toolkit — one small native binary for macOS, Windows, and Linux. MIT-licensed, because the aim was to build the best tool in this category and give it away.
Install
Prebuilt binaries for macOS, Windows, and Linux are on the releases page — download, unpack, run. Or build it with cargo:
Rust 1.88+ for the cargo route. On Linux it needs build dependencies first:
macOS asks for Screen Recording permission on first run — docs/TROUBLESHOOTING.md covers it.
Sixty seconds
# → Downloads/pixelcoords-captures/<timestamp>/
# session.json screenshot-0.png cutout-primary-0.png cutout-inverse-0.png crop-0-submit.png
# exit 0: that point is inside the region you labeled "submit"
# --stdin scores a whole trajectory in one process, one point per line
# where to click, right now, in the units your input API actually wants
# ready-to-paste click code, coordinate conventions already handled
# block until that region is back on screen; exit 1 if it never arrives
# did those regions still look right? visual regression, per region
# the UI moved? every region re-located by its saved crop, deltas included
# also an index, or part of a display's name: --monitor 0,DELL
Window-attached sessions with --target "Title" (macOS/Windows/X11)
or --pick (Wayland): drawing is locked to the window, and every mark
records window_px alongside the usual coordinates so the session stays
valid when the window moves. Freezing every screen stays the default;
--monitor narrows it, [capture] monitors makes that permanent for a
double-clicked launch, and R releases one display mid-session while the
rest stay frozen. Every command speaks exit codes and JSON where a
script would care — the complete reference with every flag is
docs/CLI.md.
Controls
Drag draws; the on-screen panel teaches everything else. The six that
matter: W cycles the tool, A labels, S saves, Z undoes, hold M
for a pixel loupe, Esc backs out / quits. Full table in
docs/CLI.md; every key is rebindable via
docs/CONFIGURATION.md.
Platform status
| Platform | State |
|---|---|
| macOS | Supported — primary development platform |
| Windows | Supported — verified by hand on Windows 11 |
| Linux (X11) | Supported — verified by hand on GNOME 46; every feature works |
| Linux (Wayland) | Screen coordinates + --pick window marking — verified by hand on GNOME 46; no windows / --target (the protocol withholds window geometry) |
Multi-monitor and mixed-DPI are now verified on real hardware, on
macOS: two displays at different scales (a 2x built-in and a 1x external
sitting at a negative desktop origin), marks placed on both, and every
coordinate recorded exactly where it was drawn. find relocated a region
on the second display at a perfect score, and releasing one display left
the other frozen and markable. Linux and Windows multi-monitor remain
test-only. This table is kept honest — claims match runs.
Acting on what you marked
pixelcoords answers where is this thing, exactly. It deliberately stops there — it never moves your mouse or types for you.
pixelactions is the other half of that loop: it reads a session, performs the interaction — click, type, chord, drag, scroll — and confirms it landed, refusing to act on any region it cannot still find unambiguously.
Driven from a chained command, a reviewable flow file, or a line protocol any language can speak. Its logic layer is pixelactions-core, the way pixelcoords-core is this tool's. Separate binary, separate repository, one-way dependency: this project does not know it exists.
Non-goals
Knowing what a tool is means knowing what it isn't. These are settled:
- OCR — text extraction is a different product; platform tools and Shottr own it.
- Live (unfrozen) measurement — the freeze is the thesis: nothing moves between look and click.
- Annotation — arrows, blur, and highlights are a screenshot editor's job; labels here exist for machines, not slides.
- Recording / GIF capture — the product is the frozen instant, not the timeline; ShareX exists.
- Cloud upload, sharing, accounts — offline by design, permanently.
- Performing the interaction — clicking and typing is a different threat model and a different tool; see pixelactions above.
Documentation
- pixelcoords.dev — the website: demo, comparisons, how-to
- docs/CLI.md — every command, flag, control, and exit code
- docs/OUTPUT.md — session.json schema, crops, cutouts, jq recipes
- docs/CONFIGURATION.md — colors, key bindings, config file
- docs/TROUBLESHOOTING.md — fixes, behaviors, FAQ
- docs/DEVELOPMENT.md — building from source, CI gates, tests, releases
- CHANGELOG.md — what changed and why
- CONTRIBUTING.md — bug reports and pull requests
- pixelactions — the executor half: act on a session, and confirm it landed
License
MIT — see LICENSE. Bundled: JetBrains Mono (OFL 1.1).
Built by nolindnaidoo.