circle(element, options)
A slightly imperfect loop around anything worth a second look.
Built for coding agents and developers. Install Stet, then use project skills with your agent or attach annotations directly through the typed API. Your existing UI keeps its controls and layout.
Stet is ESM only. The core has no runtime dependencies; install your chosen framework separately. Version 0.1.0 is an early release, so the examples pin the version.
Install Stet’s project skills from your app directory. The CLI requires Node.js 20 or newer.
Choose codex, claude, cursor, or opencode for your tool. The skills cover implementation, UI review, educational feedback, and feature emphasis.
Try a request like:
Use Stet to annotate this settings screen. Draw attention to the fields that need review, preserve the existing layout and controls, and check the result in the browser.
The agent inspects your project and installed capabilities, validates an annotation plan, and adapts a framework example. Review the source and live result together: a valid plan cannot prove that a mark points to the right control or leaves text readable.
Agent setup and workflowAttach a mark to a real element. Choose your framework for an example with setup and cleanup.
"use client";
// Adapt these sample elements to existing source; retain their semantics and handlers.
import { useRef } from "react";
import { Circle } from "@funsaized/stet/react";
import "@funsaized/stet/style.css";
export function AnnotatedAction({ enabled = true }: { enabled?: boolean }) {
const target = useRef<HTMLButtonElement>(null);
return <>
<button ref={target} type="button">Review action</button>
{enabled && <Circle target={target} seed={42} description={"Review this action before continuing."} />}
</>;
}
Always import the stylesheet. In React, annotation components render nothing and attach to a DOM ref after mount. The other adapters fit their framework’s native patterns.
Stet measures a target and adds a pointer-transparent SVG overlay. Your element keeps its layout, clicks, keyboard focus, and semantics. Notes use real HTML for readable text.
Marks update on target and parent resize, viewport resize, and nested scrolling. With the vanilla API, call refresh() after application-driven movement that doesn’t resize the element, and destroy() before removing the target. Framework adapters handle cleanup for you.
circle(element, options)A slightly imperfect loop around anything worth a second look.
underline(element, options)A hand-drawn stroke that follows the text, even when it wraps.
highlight(element, options)A translucent sweep of color. Your words still do the talking.
arrow(from, to, options)Connect two real elements with a curved arrow and an optional label.
Both endpoints must be real elements. Add label and adjust curvature to shape the connection.
sticky(element, options)A little paper note for context, encouragement, or a friendly nudge.
Requires text. Choose a preferred side: auto, top, right, bottom, or left.
mark(element, "right", options)Give feedback with a handwritten check or cross.
Use "right" for a check or "wrong" for a cross.
| Option | What it does | Default |
|---|---|---|
stroke | Ink color for strokes | CSS token |
fill | Highlight or sticky paper color | CSS token |
width | Stroke width in pixels | 2.2 |
roughness | How imperfect the sketch feels | 1 |
seed | Repeatable geometry | Random |
boil | Optional frame variation | 0 |
resketchOnHover | Fresh marks on pointer entry and press | false |
description | Accessible meaning for a mark | None |
Set defaults with CSS custom properties such as --stet-stroke, --stet-fill, and --stet-paper. Framework option changes reattach the annotation. In vanilla, destroy and reattach to change options.
Stet is still by default. Set boil: 0.3 for subtle living ink, or enable resketchOnHover. Both honor reduced-motion preferences, including changes while the page is open.
Decorative marks don’t create tab stops or intercept pointer events. When a mark communicates meaning, give it a description; don’t rely on color alone. Sticky text and arrow labels describe their targets automatically.
Stet requires modern browser DOM APIs, including ResizeObserver. Arbitrary transforms, top-layer dialogs, and cross-document targets have placement limits. Read the complete reference before adding marks to complex layouts.
Read the full API reference