Introduction
An open-source, config-driven, agent-native visual decision-lock — clickable option tiles in, a deterministic build brief out.
A visual-design decision usually dies in a document. Someone writes "warm, editorial, not corporate," three people picture three different things, and the build pass guesses. Loupe replaces that paragraph with something you can click.
You describe the decision as a typed config. Loupe turns each choice — an image crop, a color palette, a type specimen, a motion feel, a layout mock — into a real, rendered option tile. Locking a tile recomposes a sticky live preview and keeps a deterministic export brief in sync. That brief, markdown and JSON, is the ground truth the next build pass consumes — whether the builder is a person or an agent.
typed config → rendered option tiles → lock picks → deterministic export briefLock a tile below and watch the preview and the brief move with it. This is the real React adapter, themed with the Night Atlas tokens — nothing is mocked.
The wedge
Most "design decision" tooling makes you choose between two bad options: a Figma board nobody can diff, or a text log nobody can see. Loupe sits exactly between them.
- It is seen, not described. Every option renders the actual thing — a real crop of a real board, a real type family at a real weight. The decision-maker sees what they are choosing.
- It is the contract, not a screenshot of one. The export brief is derived from the same selections that drive the preview, so the preview and the brief can never drift. Hand the brief to a build pass and it is exact.
- It is agent-native. The config is a Zod schema;
toJsonSchema()emits the exact contract an agent fills. An agent can author a decision-lock, screenshot-verify it, and export the brief without a human writing TypeScript. - It is portable. The generator produces one self-contained
index.html— JS and CSS inlined, assets copied beside it — that runs underfile://or any static host with zero runtime dependency on these packages.
Loupe is the tool we built to lock our own product and brand decisions, then released. The same machinery drives the IAS control plane, the Human Today art direction, and this site.
Install and use
There are two ways to consume Loupe, and they cost very differently. Default to the first.
The primary path needs no published packages. Author a loupe.config.ts, run the generator from the monorepo, and take the self-contained artifact.
# from the monorepo, in a dir that can resolve @lucentive-labs/loupe-generator
tsx generate.ts # → dist/index.html + dist/assets/* (portable)The generated index.html is everything: the interactive picker, the live preview, the export brief, the copy button. Drop it in a PR, a bucket, or a teammate's machine. See the agent method for the full explore → author → generate → verify → export loop.
When a shipping app needs the picker live in its own UI, mount the React adapter and import the canonical styles once.
pnpm add @lucentive-labs/loupe-react @lucentive-labs/loupe-dom @lucentive-labs/loupe-schemaimport { Loupe } from "@lucentive-labs/loupe-react";
import "@lucentive-labs/loupe-dom/styles.css"; // import once, app-wide
import { config } from "./loupe.config";
export default function Page() {
return <Loupe config={config} />;
}The @lucentive-labs/* packages are not published yet (all at 0.0.0). The React-component path activates once publishing is enabled; until then, use the portable artifact — it needs no registry at all. The packages reference documents every export regardless.
The packages
Loupe is a small set of layers. The headless core holds all the logic; everything above it is a thin renderer.
loupe-schema
The Zod config contract a human or agent fills — Config, parseConfig, toJsonSchema, validateConfig.
loupe-core
Zero-dependency headless core — the store, the derivations, the crop math, the theme tokens.
loupe-dom
The canonical vanilla renderer — mount, renderToString, and the shared styles.css.
loupe-generator
The Node-only builder that emits the self-contained portable artifact.
loupe-react
The React 19 adapter — <Loupe /> and the headless useLoupe() hook.
Where to go next
Quickstart
Author a config, render it, read back the brief.
Core concepts
Groups, options, specimens, the composed preview, and the export brief.
The crop model
Normalized rects, the exact cover math, and a live crop you can switch.
Interactive tutorial
Edit a config in the browser and watch the brief recompute.