Packages / API
The five Loupe packages, how they layer, and where each export lives.
Loupe is layered so the logic lives in exactly one place. The headless core owns all state, derivations, crop math, and theming. Every renderer above it is a thin view that calls the same core functions, which is why the vanilla output, the React component, and the static artifact are pixel-for-pixel and brief-for-brief identical.
loupe-schema the Config contract (Zod) — the source of truth
│
loupe-core headless: store · derivations · crop math · tokens · a11y
╱ ╲
loupe-dom loupe-react thin renderers over core (identical DOM + classes)
│
loupe-generator Node-only: bundles loupe-dom into one portable HTMLA few rules fall out of this shape:
- Schema is the contract. Types are inferred from Zod, and
toJsonSchema()emits the exact contract an agent fills. Nothing downstream redefines the shape. - Core is the brain. If a behavior is interesting — single-select, the preview composition, the export brief, the crop math — it is a pure function in core. Renderers do not re-implement it.
- Renderers are thin and aligned.
loupe-domandloupe-reactemit the same class names,data-*attributes, and ARIA, so the sharedloupe-dom/styles.cssstyles both.
The packages
loupe-schema
Config, parseConfig, toJsonSchema, validateConfig — the typed, validated contract.
loupe-core
createLoupeStore, the select* derivations, cropToCss, connect, the token helpers.
loupe-dom
mount, renderToString, applyTheme, the render functions, and styles.css.
loupe-generator
generate(config, opts) — validates, copies assets, inlines JS + CSS into one HTML file.
loupe-react
<Loupe />, useLoupe, normalizeProps, TILE_AR.
All packages are currently 0.0.0 and unpublished. The signatures documented here are the real exports from source; the portable-artifact path (agent method) runs them straight from the monorepo with no registry.