# Mesurer bolts a measuring tape onto your app so you can argue about spacing in pixels

> Mesurer is a React component that adds a UI inspector to a live app, with guides, rulers, measurements, arrows, pen strokes, text notes, colour picking and X-ray mode, plus a comments workflow aimed at handing precise visual feedback to a coding agent. It is a developer tool that ships inside your bundle.

**ibelick/mesurer** — Inspect, annotate, and give feedback on any live interface.

- Repository: https://github.com/ibelick/mesurer
- Website: https://mesurer.dev
- Stars: 566 · Forks: 30
- Language: TypeScript
- License: NOASSERTION
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/ibelick-mesurer

## A component you mount, not a bookmarklet

Mesurer is described as an open source UI inspector and visual feedback tool for the browser, and the tagline is that you can inspect, annotate and give feedback on any live interface.

The mechanism matters here. Mesurer is not a browser extension and not a separate service. It is a React component you add to your application, and the README's usage example is the whole integration.

```tsx
import { Mesurer } from "mesurer";

function App() {
  return (
    <>
      <YourApp />
      <Mesurer />
    </>
  );
}
```

The component sits next to your app rather than wrapping it, which means the toolbar and the overlays live inside your own React tree and your own build.

The design goal is stated in one line: Mesurer runs directly where you build, and you share feedback with your agents and your team. The features list names guides, rulers, measurements, arrows, freehand pen strokes, text annotations, colour inspection, typography tools, X-ray mode and screenshots, and it adds the ability to capture a short video of any visible region to show interaction details that a screenshot cannot.

The primary language of the repository is TypeScript, the homepage is mesurer.dev, and the package is published to npm as mesurer.

## What the props actually control, and the defaults that surprise people

There are about two dozen props, and most of them are switches rather than settings, which is the main thing to understand before you use it.

The colour props are the ones with real values. highlightColor is the base colour for selection and hover overlays and defaults to oklch(0.62 0.18 255). guideColor is the base colour for guides and defaults to oklch(0.63 0.26 29.23), and arrowColor carries the same default.

The rest are booleans, and their defaults are worth reading rather than assuming. guideHighlightEnabled, layoutDetailsEnabled, persistOnReload, shortcutsEnabled, snapEnabled, snapGuidesEnabled, snapArrowsEnabled and selectNewGuideEnabled all default to true. multiMeasureEnabled defaults to false, so a previous measurement is cleared rather than kept, and arrowClickToPlace defaults to false, so arrows are placed by dragging rather than by clicking.

The features prop is the coarse switch: you can enable or disable screenshot, rulers, settings and responsive, and each of those defaults to true.

Two props are about where and how state lives. persistKey is an optional workspace storage key, and by default workspaces are isolated per browser tab. persistence is an optional storage adapter for custom or extension-backed persistence. And portalTarget is an optional element or shadow root used as the overlay portal mount target, which matters if your app has its own stacking contexts or renders into a shadow root.

The persistence story has one detail that will bite you. The props are the defaults, saved settings override them, and Use defaults restores the props. So a setting a user changed once will survive a code change to the default value, which is the right behaviour for a tool and a surprise for a developer.

## The keyboard map, including the duplicate V

The commands table is a single letter per mode, and it is the fastest way to learn the tool.

M toggles Comments mode, I toggles Inspect mode, S toggles Select mode for annotations, A toggles Typography mode, D toggles Arrows mode, N toggles Pen mode, T toggles Text mode, G toggles Guides mode, and X toggles X-ray mode. R toggles pixel rulers along the top and left edges, and B previews the page at other screen sizes. The digit keys 1 and 2 switch between the Select and Inspect tools and the Annotate tools. P opens the native colour sampler. C drags a region of the visible tab for a screenshot, and V drags a region of the visible tab to record a video. H sets guide orientation to horizontal, and V sets guide orientation to vertical.

That last pair is a documentation defect worth flagging, because V is listed twice with two different meanings. In the table as written, V both records a video and sets guide orientation to vertical, which cannot both be true of one key. If you rely on the vertical guide shortcut, check the actual implementation rather than the table.

The rest of the map is more predictable. Alt temporarily enables the option and guide measurement overlays, and Option + S or Alt + S pins the measurement currently shown so it stays on screen. Esc closes an open panel, cancels the current interaction or deselects the tool, and pressing it again minimizes Mesurer. Backspace or Delete removes selected guides, arrows, pen strokes or text. Cmd or Ctrl with Z undoes, with Shift and Z redoes, with A selects all annotations, with a comma opens Settings, and with K copies the comments for an agent.

## The initialState object, and what saved state overrides

There is one more entry point beyond the props, and the README describes it in a single sentence.

initialState accepts enabled, minimized, toolbarPosition, toolMode, guides, arrows, pen strokes, text annotations, measurements, and comments. Saved workspace state overrides it.

That ordering is the important part. initialState is a starting point, not a guarantee. Once a workspace has been persisted, the saved state wins, which is what makes the tool usable across sessions, and it is also why a developer who changes initialState and sees no effect needs to clear the stored workspace rather than look for a bug.

The example the README gives is a component that starts minimized with the toolbar positioned at a specific point.

```tsx
<Mesurer initialState={{ minimized: true, toolbarPosition: { x: 24, y: 24
```

The snippet in the README is cut off at that point, so the closing braces and the rest of the object are not visible, but the shape is clear from the property list above it.

The two things a user of this API has to design for are the toolbar position and the tool mode, because those are the two values a team usually wants to standardise, and they are the two values that saved state will override. If your project wants a consistent default for every developer, the persistence layer and the reset path are where that decision has to be made.

## A monorepo with a package, a site and an extension

The repository is a pnpm workspace with apps/ and packages/ directories and a pnpm-workspace.yaml, and the scripts show what is inside it.

The build script builds the package and the site, build:extension builds the extension, and build:pkg builds only the package. There are separate dev scripts for the package and the site, and a dev script that runs both in parallel with pnpm --parallel -r dev.

So there are at least three artefacts here: the React package, the documentation site deployed with a pages deploy script, and a browser extension. The extension is the interesting one for the audience question, because the package is what you mount in your app and the extension is what runs in the browser when you are inspecting somebody else's.

The check scripts show how the project is guarded. check:types runs a typecheck on the package, a build, and then a noEmit typecheck on both the site and the extension. check:push runs the type checks, the site build and the extension build, and check:release adds the tests on top. The order is deliberate, types first, then build, then tests, and the release script is gated behind all of it.

The root package.json also holds husky, with a prepare script that installs it, and there is a .husky/ directory in the tree. The lint script runs pnpm -r lint across the workspace and the test script runs pnpm -r test, so each package is linted and tested on its own rather than as one unit.

## Where Mesurer is the wrong choice, and the licence question

Three cases, and one of them is a licensing detail to settle first.

The first is that Mesurer is a developer instrument that runs in your users' browsers. Because it is a component in your app, the decision to include it in a production build is yours, and nothing in the README suggests a build time exclusion. A tool that draws overlays on your interface, records video of a region of the tab and persists a workspace belongs in development builds, and shipping it means shipping a UI inspector to your users. The features prop and the enabled flag in initialState are the levers, but the exclusion has to be done by you.

The second is what it is not. Mesurer measures and annotates an existing interface, and it does that well. It is not a design system, not a component library, and not a way to change how your product looks. The typography tools and the X-ray mode are for reading a layout, and if your problem is that the layout is wrong, the output is a measurement rather than a fix.

The third is the licence, and the repository is genuinely unclear. The project metadata records the licence as a custom one that GitHub cannot classify, with the terms in the LICENSE file, while the package.json in the repository says MIT. Two different answers for the same repository, and for a tool that ships inside your product that is worth resolving before you ship it.

On maintenance, the repository is not archived and the last push was on 2026-10-14, with releases 0.2.7 on the same day, 0.2.6 the day before and 0.2.2 on 2026-10-01. The version is still 0.2.x and it is moving quickly, so the props and the key map are likely to change under you. The version, the shortcuts and the defaults are all worth pinning in your own notes, because the README will not hold still for long.

## Conclusion

Adopt Mesurer if you are building a React interface and want a built in way to measure spacing, collect visual feedback and hand precise annotations to a coding agent without leaving the app. Do not adopt it as a production dependency, since it runs in your users' browsers, and do not expect a theme or a general design system from it, because its job is inspection rather than design. Before you ship it, decide whether the inspector ships disabled in production, and read the persistence props, since the default keeps workspace state in the browser.

## FAQ

### How do I install Mesurer?

Run npm install mesurer. The package is published to npm as mesurer, and the usage example mounts the Mesurer component alongside your app with an import from the package.

### What does the Mesurer component do?

It is an open source UI inspector and visual feedback tool for the browser, providing guides, rulers, measurements, arrows, freehand pen strokes, text annotations, colour inspection, typography tools, X-ray mode and screenshots, and it can capture a short video of a visible region to show interaction details a screenshot cannot.

### How does Mesurer store its workspace state?

The props are the defaults, saved settings override them, and Use defaults restores the props. The persistOnReload prop persists workspace state across reloads and defaults to true, persistKey names an optional storage key, and by default workspaces are isolated per browser tab.

### Which keyboard shortcuts does Mesurer use?

M toggles Comments, I Inspect, S Select, A Typography, D Arrows, N Pen, T Text, G Guides and X X-ray, R toggles pixel rulers and B previews other screen sizes, while 1 and 2 switch tool groups and P opens the native colour sampler. The README table lists V twice, for recording a video and for setting guide orientation to vertical.

## Sources

- [ibelick/mesurer on GitHub](https://github.com/ibelick/mesurer)
- [Issues](https://github.com/ibelick/mesurer/issues)
- [Project website](https://mesurer.dev)
- [README](https://github.com/ibelick/mesurer/blob/main/README.md)
- [Releases](https://github.com/ibelick/mesurer/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ibelick-mesurer
