@ui-organized/ui-inspect
v0.2.0
Published
A design-system inspector for local development. Click any element in your running dev app, see its properties resolved against that project's design tokens, and edit them.
Downloads
631
Maintainers
Readme
@ui-organized/ui-inspect
A design-system inspector for local development. Click any element in your running dev app, see its properties resolved against that project's design tokens, and edit them live.
It reads the tokens your page already defines — by default the :root custom
properties — so there is nothing to configure. It is not tied to
@ui-organized/react: it inspects whatever design system the page actually
ships, including none.
Install
npm i -D @ui-organized/ui-inspectUse
Mount it from your app entry, guarded so it never reaches production:
if (import.meta.env.DEV) {
const { mountInspector } = await import("@ui-organized/ui-inspect");
mountInspector();
}Then click the Inspect button the package mounts in the page, and click any element. The inspector binds no keyboard shortcuts, so it never swallows a keystroke meant for your app.
Not using Vite? Any dev-only guard works — process.env.NODE_ENV !== "production",
a bundler define, or simply not importing it in your production entry. The
dynamic import() keeps it out of the production bundle entirely.
What you get
- Values resolved against your tokens. Every property shows its computed value and which token it matches, if any.
- Matching by resolved value type (
color/length/number/family), never by token name. A property is only audited when your system actually defines tokens of that type, so you never get an "everything is broken" score. - A drift score — how far the page has strayed from the token scale.
- A component inventory with recovered component identity, plus the provenance and confidence of that identification.
- Live edits as CSS rules, never inline styles. Edits go into a single
rebuilt
<style>element. - Edits that survive a reload. The change set is saved per page and re-applied on the next visit, and re-anchored when your app re-renders. See Persistence.
Options
mountInspector(options?) returns { engine, destroy }.
const inspector = mountInspector({
// start expanded instead of collapsed to the launcher button
expanded: true,
// where tokens come from — default is the page's own :root custom properties
config: {
source: "css-vars", // "css-vars" | "dtcg" | "tailwind" | "json"
root: ":root",
include: "", // substring filter for token names
exclude: "",
},
});
inspector.destroy(); // unmount and clean upengine is the headless inspection engine, exported here too if you want to
drive it without the panel.
Persistence
Edits are saved automatically, keyed by origin + pathname, and re-applied the next time you open that page. The panel's status line always names where they are going, because the answer depends on the host:
| Backend | When |
| --- | --- |
| localStorage | a normal dev page |
| host storage (window.storage) | sandboxed preview hosts that provide one |
| chrome.storage.local | extension context |
| in-memory | nothing above is available — edits are lost on reload, and the status line says so |
Two things this is not. It is not a write to your source files: the change set lives in browser storage, and the Changes tab is still where you export JSON or a markdown change doc to apply for real. And browser storage is per-profile and per-origin — a devtools "clear site data" wipes it.
The panel also re-anchors its edits when your app re-renders, so a local edit survives a state update rather than evaporating with the replaced node.
Clear all in the Changes tab reverts every edit on the page and wipes the stored set.
To opt out, or to supply your own backend:
mountInspector({ storage: false }); // session only, nothing written
mountInspector({ storage: myBackend }); // any { name, label, durable, get, set, remove }
mountInspector({ storageKey: "uii_checkout" }); // share one set across routesNotes
- Self-contained. React and every other dependency are bundled in, so
dependenciesis empty. It drops into a React, Vue, Svelte or plain-HTML dev app the same way and cannot conflict with your app's React version. - CSS-isolated both ways. The panel renders inside a shadow root, so the host page's CSS cannot reach into the panel and the panel's cannot leak out.
- Dev-only by design. It is a development tool; keep it behind a dev guard.
- ESM only.
License
MIT
