Draw on bugs. Let AI fix them.

npm i usemarkupkit

MarkupKit turns freehand drawings into structured context AI coding agents can act on. Six annotation modes. Seven shape types. Four output levels. Spacing visualization, contrast checking, animation pause, localStorage persistence, screenshot capture, and source file detection.

Annotation modes

Six ways to annotate. Click the tabs to try each mode:

Monthly Revenue

$124,500 — up 12% from last month

Active Users

8,241 daily active users

"You have to work hard to get your thinking clean to make it simpl."
Export ReportView Details
Draw circles, arrows, or lines — note input appears after each stroke

Shape detection

Every drawing stroke gets classified with a confidence score. Seven types: circle (enclose elements), arrow (relate elements), strikethrough (remove text), underline (emphasize), cross (delete), rectangle (select area), freehand (fallback). The classifier scores each type and picks the highest above 0.35.


Smart identification

MarkupKit builds CSS selectors the way you'd search for them in code. Hover any element below:

localhost:3000/@dragoon0xHover
Dragoon
@dragoon0x
Follow

Building tools for the agentic web.

Hover any element to see its selector

React component detection

Reads the fiber tree via __reactFiber$ keys, falls back to data-component and data-testid attributes. Component names appear in the output alongside CSS selectors.


Spacing visualization

When hovering elements, MarkupKit renders padding as green zones and margin as amber zones on the canvas overlay with pixel values labeled. Toggle on/off in settings. Uses getComputedStyle to read live values.


Contrast checking

Every text element gets its WCAG 2.1 contrast ratio calculated from color and backgroundColor. The ratio, AA pass/fail, and AAA pass/fail appear in detailed and forensic output. Try the live checker:

Text
Background
16.0:1
AA ✓AAA ✓
Sample

Output

Four detail levels. Click each tab to see the same annotations rendered at each level:

Source file detection — reads _debugSource from the React fiber and data-source / data-file attributes. Appears at detailed and forensic levels.

Screenshot capture — click 📷 in the toolbar to download the annotation canvas as a PNG.

localStorage persistence — annotations survive page refresh. Toggle on/off in settings. Stored under markupkit_annotations.


Layout Mode

Annotations tell the agent this is wrong. Layout Mode tells the agent here's what I want instead.

Select an element, drag it somewhere new, resize it, drop a wireframe component from the palette. Every change is tracked with precise coordinates. Hit copy, paste into Claude Code or Cursor, and the agent applies it in one pass.

This demo is live. Click any element to select it. Drag to move. Drag the blue handles to resize. Click + Components to drop wireframe primitives.

Get Started
Revenue
$24,500
Users
1,247
Conversion
3.2%
Components
Structure
Section
Card
Content
HHeading
Text Block
Input
Button
Input
Media
Image
Navigation
Navbar
Tabs
Agent output0 changes
// Drag, resize, or add elements above. Output appears here live.
↕ Drag to move
Delta captured: →12px, ↓8px. Snaps to sibling edges and centers.
⇲ Resize handles
8 handles. Drag edges or corners. 24px minimum enforced.
⊞ Alignment guides
Blue dashed lines snap at 6px threshold. Optional 8px grid.
🃏 Component palette
9 wireframe primitives. Drop cards, navbars, inputs, images.
📋 Structured diffs
Type, selector, from/to rects, pixel deltas per change.
✨ CSS suggestions
Detailed level outputs transform and dimension CSS.
enable layout mode
<Markup layout />  // adds drag + resize + palette

Install

terminal
npm install usemarkupkit -D
layout.tsx
import { Markup } from 'usemarkupkit'

function App() {
  return (
    <>
      <YourApp />
      {process.env.NODE_ENV === "development" && <Markup />}
    </>
  )
}

Agent sync — pass endpoint to sync annotations to a server. Sessions are created on mount, annotations POSTed on change. Pass sessionId to rejoin an existing session. onSessionCreated fires when a new session is created.

with endpoint
<Markup
  endpoint="http://localhost:4747"
  onSessionCreated={(id) => console.log("Session:", id)}
/>

Props

All optional. Works with zero configuration.

enabledEnable/disable (default: true)
colorStroke color (default: "#171717")
strokeWidthStroke width in px (default: 3)
tool"draw" | "arrow" | "circle" | "eraser"
detail"compact" | "standard" | "detailed" | "forensic"
toolbarShow toolbar (default: true)
positionToolbar corner (default: "bottom-right")
rootScope selector (default: "body")
ignoreTags to skip (default: [])
shortcutToggle shortcut (default: "ctrl+shift+d")
copyToClipboardWrite to clipboard (default: true)
onAnnotationAddCalled when annotation created
onAnnotationDeleteCalled when annotation removed
onAnnotationUpdateCalled when note edited
onAnnotationsClearCalled when all cleared
onCopyCalled when copy clicked (receives markdown)
onDrawCalled per-stroke with DrawEvent
endpointServer URL for syncing annotations
sessionIdPre-existing session to rejoin
onSessionCreatedCalled when new session created

Programmatic API

script.ts
import {
  detectShape, resolveShape, formatSession,
  resolveClickedElement, resolveTextSelection,
  resolveAreaSelection, getElementSpacingAtPoint,
  contrastRatio, smoothPoints, strokeBounds
} from 'usemarkupkit'

// Shape detection
detectShape(stroke) // → { type: 'circle', confidence: 0.87 }

// Element resolution for each mode
resolveClickedElement(x, y) // → Annotation from click
resolveTextSelection()      // → Annotation from window.getSelection()
resolveAreaSelection(bounds) // → Annotation from rectangle

// Spacing + contrast
getElementSpacingAtPoint(x, y) // → { spacing, rect }
contrastRatio('rgb(23,23,23)', 'rgb(255,255,255)') // → 16.0

Keyboard shortcuts

Ctrl+Shift+DToggle on/off
EscCancel / close
PPause/resume animations
HHide/show markers
CCopy annotations
XClear all

Settings

The ⚙ button in the toolbar opens the settings panel. All settings are wired and take effect immediately:

Output DetailStandard
Spacing Viz
Contrast Check
React Components
Source Detection
Persist (localStorage)
Clear on Copy
Block Interactions

~10kb gzipped · zero dependencies · React 18+ · MIT