@ui-organized/ui-inspect-vite
v0.1.1
Published
Vite plugin for UI.Inspect — mounts the inspector in dev with your project's own design tokens, read from disk, and writes copy edits back to source.
Maintainers
Readme
@ui-organized/ui-inspect-vite
Click any element in your running Vite dev app, see its properties resolved against your project's own design tokens — read from disk, not scraped from the DOM — edit them, and write copy changes back to your source.
npm i -D @ui-organized/ui-inspect-vite// vite.config.js
import uiInspect from "@ui-organized/ui-inspect-vite";
export default {
plugins: [react(), uiInspect()],
};Start the dev server. The inspector is there. Your app imports nothing.
Zero configuration
It finds your tokens by looking, in this order:
| It finds | Because you have |
| --- | --- |
| tailwind.config.* | Tailwind |
| tokens.json / *.tokens.json | DTCG tokens |
| theme.ts / theme.js | a theme module |
| a stylesheet that really declares --custom: properties | plain CSS |
Nothing found is not a failure — it falls back to the page's own :root custom
properties. The dev server prints what it picked:
[uiinspect] tokens: src/tokens.css
[uiinspect] tokens: src/tokens.css (47 tokens)Reading from disk is the point. DTCG descriptions and aliases, and SCSS/Less
variables the compiler folds away before a browser ever sees them, all exist in
the source and never survive into the runtime DOM. .ts themes are evaluated
through Vite's own module loader, so a tailwind.config.ts works.
Edit that file and the panel re-matches live — no reload.
Copy edits, written back to your source
Select a text element, rewrite it in the panel's Content field, then Changes → Apply to source. The string is found in your project and replaced; HMR reloads; the overlay disappears. The edit stops being a preview and becomes the file.
[uiinspect] wrote src/App.tsx:69 — "Ship faster" → "Ship with confidence"It writes only when exactly one place could have produced the string. Two matches is a refusal with a reason, never a guess:
✕ "Save" appears in more than one file — too ambiguous to write
✕ "Clicks: 42" is not in any source file — it may be interpolated or come from dataRefused changes stay staged and still export as JSON or a markdown change doc.
Every write is contained inside your project root (checked after symlinks),
validated against the syntax it lands in, made via temp file + rename, and
printed to the console. Restrict it further with allowPaths, or use
dryRun: true to see what would happen.
Options
uiInspect({
enabled: true, // false turns it off without removing the plugin
expanded: false, // start open instead of collapsed to the launcher
tokens: { path: "./src/tokens.css", root: ":root", include: "", exclude: "" },
allowPaths: ["src/**"],
dryRun: false,
});Utility frameworks ship their whole palette as variables, which makes nearly
every colour read as "on-token". Narrow it with tokens.include (e.g.
"brand|semantic") or tokens.exclude for numbered ramps.
A uiinspect.config.json at your project root supplies the defaults; these
options override it.
Dev only
The plugin is apply: "serve" — it does not participate in a production build at
all. The injected client is additionally wrapped in a
process.env.NODE_ENV !== "production" guard, and its import of the panel is
dynamic and inside that guard, so there is never a static edge from your app into
the tool. Install it as a devDependency, always.
License
MIT
