Docs
Claude Code plugin
The plugin is the fastest way to keep Claude on your design system. It bundles three things:
A hook that runs
onsystem checkon every.tsxor.jsxfile Claude writes or edits, and hands the errors back so they get fixed in the same turn instead of in review.The MCP server, so Claude can look components, props, variants and tokens up before it writes.
A skill that tells Claude to do that, and to fix every
check_uifinding. It loads by itself for UI work, or run/onsystem:onsystem.
/plugin marketplace add dgesteves/onsystem/plugin install onsystem@dgestevesWhat Claude sees when it invents something
⏺ Write(app/promo/page.tsx) ⎿ PostToolUse hook: app/promo/page.tsx breaks the project's design system 1:58 error [no-hardcoded-color] Hardcoded color `bg-[#f5f5f5]` → `bg-muted`. 1:77 error [prefer-design-system-component] Native <button> where the design system has <Button>. …⏺ The hook flagged five issues. Looking up Button and the color tokens before fixing.⏺ onsystem - get_component (MCP)(name: "Button")⏺ Write(app/promo/page.tsx) → <Button variant="destructive"> on bg-muted, hook passesWhat the hook does
Errors come back to be fixed. The hook runs after the file is written. It exits with Claude Code's blocking-error code, and the findings, each with its fix, go to Claude, which corrects the file before moving on.
Warnings don't. They reach Claude as a note, without blocking.
Only what Claude just changed. After an Edit it lists the findings on the edited lines and only counts older ones. It honours a baseline.
Quiet where there is nothing to check. It stays silent in projects without design-system components (tokens alone don't count), so installing the plugin for every project is safe.
The design system's own files are left alone. Like
check, it skips them: an edit tocomponents/ui/button.tsxchanges the design system, which is a call for you and your reviewers rather than a lint error.It says when it can't check. When the CLI can't run (npx can't fetch it because of a min-release-age policy, a private registry or no network, or the config is broken), it says so once per session and project, as a message to you, and never blocks the edit.
Monorepos work. The hook finds the project from the edited file, not from where Claude started, and the MCP server started at the root serves every project, answering for the file's own project when the tools get its
path.
What it runs, and what it touches
The hook and the server run the onsystem package at the plugin's exact version: the project's own install when there is one (npm install --save-dev onsystem), else npx. Both run through Node.js directly, never a shell. They read the project's files and write only the cache (node_modules/.cache/onsystem, or the system temp folder) and a marker file in the system temp folder so the hook's notice is shown once. There are no network requests and no model calls; the only network access is npx fetching the package from the npm registry.
Coming from the design-system plugin
The plugin was called design-system before 0.4.0. Replace it:
/plugin uninstall design-system@dgesteves/plugin marketplace update dgesteves/plugin install onsystem@dgestevesIf you added the server with claude mcp add as well, remove that entry (claude mcp remove onsystem, or claude mcp remove design-system from before the rename) to avoid two copies of the tools. The migration guide lists everything else that moved.
What the skill tells Claude
Claude loads it by itself for UI work, or with /onsystem:onsystem. This is its text, from SKILL.md:
The onsystem MCP server reads this project's components (props, cva variants, parts), design tokens and component docs. Use it as ground truth: training data does not know this project's Button variants or color tokens.
Before writing UI
Find what exists:
search_componentswith the intent ("confirm a destructive action", "status label"), orlist_components.Read
get_componentfor every component you use. Use only the props and variant values it lists, the import it shows, and its parts (CardHeader, notCard.Header, unless it lists the member).Style with tokens from
get_tokens: semantic classes such asbg-destructiveortext-muted-foreground, never hex or rgb values, arbitrary pixel values (p-[13px]) or Tailwind's default palette (bg-red-500).Prefer a variant over overriding a component's classes, and a design-system component over a native element (
<Button>, not<button>).Give icon-only buttons an accessible name (
aria-label).
In a monorepo, apps can use different design systems. Pass the file you are editing as path to list_components, get_component, search_components and get_tokens, and as filename (or path) to check_ui, so the answers come from that file's own project.
After writing UI
Run check_ui on every file you changed and fix every error. Each finding has a rule id, a location and usually the exact fix. In Claude Code, the plugin's hook also runs the same check after each edit and reports errors back to you; fix them before moving on rather than working around them.
If the project has an onsystem.baseline.json, the command-line check (and the hook) report only findings the baseline does not already accept. check_ui shows everything in the file; fix what you introduced, and leave unrelated pre-existing findings alone unless asked.
Generated from docs/plugin.md when the site is built.