BXUP Track progress & test yourself — free
Frontend & Mobile · Module · ~9 min read
FRONTEND & MOBILE · MODULE

Component Development on Your Design System

Default AI output is generic Tailwind soup that matches nothing you own. This module makes generators land on your system — instruction files and exemplars condition them, registry and Storybook MCP servers ground them in real component APIs, and schema-first patterns make forms, state, and data layers verifiable instead of plausible.

  1. MONDAY

    Arjun owns the design system at a mid-size e-commerce company: 40 components, tokens, Storybook, three product teams consuming it.

  2. THE PR

    A product engineer ships an AI-generated checkout widget. It contains a hand-rolled <CustomButton> — 80 lines duplicating Arjun's Button, with a variant="subtle" prop his Button never had and raw #6b7280 grays where tokens exist.

  3. THE PATTERN

    It's the fourth such PR this month. Each one works. Each one adds a parallel, slightly-wrong component universe the team will maintain forever.

  4. THE DIAGNOSIS

    Nobody told the generators the design system exists. The models did the statistically likely thing: emit the shadcn-flavored output their training data is saturated with.

  5. THE FIX

    Arjun stops reviewing symptoms and starts engineering the context: instruction files that name the primitives, exemplar components in the prompt, and a registry MCP server so agents query real component APIs instead of inventing look-alikes.

  6. SIX WEEKS LATER

    Generated PRs import from @acme/ui. The off-system lint he added catches the stragglers in CI, not in his review queue.

Arjun's month is the defining component-development problem of the AI era: the tools generate a design system fluently — just not yours. Left unconditioned, every assistant on the team converges on the same generic output, and your design system dies by a thousand plausible duplicates. The fix is not better reviewing. It is conditioning the generator before it types: telling it what exists, showing it what good looks like, and — at the advanced tier — wiring it to query the truth instead of trusting it to remember. This module covers that discipline end to end, then applies the same grounding mindset to the rest of the component workload: forms, Storybook, state refactors, data layers, and typed API clients.

What You'll Learn

  • Instruction files and few-shot exemplarsthe conditioning that makes any generator emit on-system code
  • Registry and Storybook MCP groundingagents fetch real props instead of hallucinating them
  • Schema-first form generationevery state enumerated before the first render
  • Storybook as the agent's verification loopstories as the visual contract
  • State and data-layer refactorsrun under characterization-test protection
  • Typed API clients and MSW mocksgenerated from the schema, drift-checked in CI

Conditioning the Generator: Instruction Files and Exemplars

Every serious assistant now reads a persistent instruction file from the repo — Copilot's .github/copilot-instructions.md, Cursor rules, Claude Code's CLAUDE.md. For frontend teams this file is the single highest-leverage artifact you can write, because it runs on every generation by every teammate. The generic version ("use TypeScript, follow our conventions") does nothing. The version that works is concrete and mechanical:

  • Name the system explicitly"All UI comes from @acme/ui. Never create a component that duplicates an existing primitive. Before writing any button, input, card, dialog, or badge, use the existing one."
  • Enumerate the tokens"Colors only via var(--color-*) / Tailwind theme tokens. No raw hex, no arbitrary values like p-[13px]. Spacing uses the 4px scale tokens."
  • State the states"Every component with async data renders loading, empty, error, and populated states. Every form field renders error and disabled states."
  • Encode the a11y floor"Interactive elements are semantic (button, a, label). Every input has an associated label. Focus states are never removed." (M5 deepens this.)
  • Point to exemplars"When generating a new component, follow the structure of src/components/DataCard/ — it is the reference implementation."

The exemplar line is the underrated half. Models are few-shot learners: one actual component from your codebase in context — with its prop patterns, token usage, test file, and story — moves output quality more than a page of prose rules. Keep two or three "gold" components deliberately polished and small, and reference them by path so agentic tools open and imitate them.

Pro Tip

Write the instruction file with an enforcement partner: an ESLint config that bans raw hex values, arbitrary Tailwind values, and imports that bypass @acme/ui. The instruction file steers generation; the lint catches what steering missed. Neither alone survives a deadline — together they hold in CI.

Registry-Grounded Generation: From Memory to Query

Instruction files reduce hallucination; they cannot eliminate it, because the model is still generating your component APIs from memory it doesn't have. The structural fix is MCP grounding: give the agent a tool that returns the truth.

A shadcn-style registry MCP server (or an internal registry server, or the Storybook MCP addon) lets the agent do what you would do — look up the component, read its actual props and variants, and install or import the real thing. The workflow difference is stark, and Lab 03 has you measure it directly by requesting the same data-table screen with and without the registry wired:

UNGROUNDED

The agent remembers

Asked for a data table, the agent emits a plausible <DataTable columns={...} striped> — a component that doesn't exist, with props it invented, styled with its training-data defaults. Everything compiles in the agent's imagination and nothing in your repo. You discover the fiction at typecheck — or worse, when it hand-rolls the whole table to make its fiction true.

REGISTRY-GROUNDED

The agent queries

The agent calls the registry, gets the real Table API — the actual prop names, the actual variants, the install command — and composes your components with your conventions. Output references reality because it fetched reality. Review shifts from "does any of this exist?" to "is this composition right?" — a senior-level question worth your time.

The same grounding logic extends to Storybook: the Storybook MCP addon exposes your stories — component inventory, states, controls — as queryable context, which both grounds generation and gives agents a render target for verification (below).

Note

Grounding is only as good as the registry. If your design system's props are undocumented or your Storybook is stale, the agent faithfully fetches garbage. Registry-grounded generation quietly forces the platform-engineering hygiene you always meant to do — that is a feature, not a cost.

Schema-First Forms: Enumerate Every State Up Front

Forms are the highest-frequency frontend task and the place where generated happy paths hurt most, because the unhappy paths carry the business logic: validation, server rejection, double-submit, dirty-state warnings. The pattern that works is schema-first with state enumeration: define the Zod schema yourself (it is the contract — human work), then have AI generate the react-hook-form wiring with the full state matrix demanded explicitly:

Given this Zod schema [paste], generate the form component using
react-hook-form + our FormField primitives (see src/components/Form/).
Enumerate and render ALL of: per-field validation errors, form-level
server error, dirty-unsaved warning, disabled-while-submitting,
submit success, and empty/initial. No state may be represented
only in comments.

Then hand-verify the unhappy paths in the browser — submit with the network failing, double-click submit, navigate away dirty. The model enumerates flawlessly when told to; it is the telling that is the skill, and the manual unhappy-path pass that is the review.

Storybook as the Agent's Verification Loop

Text-only generation is open-loop: the model emits JSX and never sees a pixel. Storybook closes the loop cheaply. The workflow: have the agent generate (or update) stories for every variant and state alongside the component; run Storybook; the agent (via the MCP addon or a screenshot tool) — and you, in two seconds of scanning — verify each state actually renders as intended. Stories become three things at once: the generation contract ("these states must exist"), the visual review surface, and the input to visual-regression gates later (M5). A component PR without stories for its states is, under this discipline, incomplete by definition — for humans and agents alike.

Refactoring State and Data Layers Under Protection

The second half of component work is not greenfield — it is evolving the client architecture you already have: prop-drilling that needs scoped stores, useEffect-fetch spaghetti that needs TanStack Query. AI is genuinely strong at the mechanical conversion and genuinely dangerous at the semantics, so the discipline is sequence:

  1. Map first. Have the agent inventory the data flow: who reads this state, who writes it, what re-renders when it changes. This read-only analysis is high-trust output — errors surface immediately when you spot-check.
  2. Pin behavior. Generate characterization tests that capture current user-visible behavior (RTL, accessible queries) before touching anything. These tests are the safety net, so review them hardest — decorative assertions here mean an unprotected refactor.
  3. Stage the refactor. Convert one slice at a time — one context to one store, one fetch to one query hook — with the pinned tests green after each step. Reject any agent plan whose first move is "rewrite the state layer."
  4. Review the semantics yourself. Cache keys, invalidation, optimistic updates, stale-time: these encode product decisions (what may be stale? what must refetch on focus?) the model cannot know. The mechanical conversion is delegated; the cache-semantics review is not.
TaskDelegate to AIKeep human
Data-flow inventoryFull read-and-map passSpot-check accuracy
Characterization testsFirst draft generationAssertion-quality review (mutation-check, M5)
Store/query conversionMechanical slice-by-slice rewriteSlice ordering, rollback decision
Cache semanticsPropose defaultsDecide staleness, invalidation, optimistic policy
Typed API client + MSW mocksFull generation from OpenAPI/GraphQL schemaDrift check in CI, edge-fixture realism

The last row is its own quick win: openapi-typescript or GraphQL codegen plus AI glue turns a schema into typed fetch hooks and MSW handlers in one pass. Put a drift check in CI (regenerate and diff against the committed client) so the contract cannot silently rot — the AI-era version of "the mock lied."

Warning

The agent's characterization tests and the agent's refactor share the same blind spots — a misread of current behavior gets faithfully preserved in both. Before trusting the pin, break the component deliberately (invert one condition) and confirm the tests actually fail. A pin that can't fail protects nothing.

Try It Now

  1. Write the instruction file. Draft your repo's generation rules today: system import path, token rules, state requirements, a11y floor, and two exemplar component paths. Commit it as CLAUDE.md / Copilot instructions and generate one small component to compare before/after.
  2. Run the grounding A/B. Ask your agent for a screen using your design system twice — once cold, once with your registry or Storybook MCP (or, minimally, with your component index pasted into context). Count hallucinated props and duplicated primitives in each. Keep the diff; it is your business case.
  3. Enumerate a real form. Take one production form you own, list its actual states, then run the schema-first prompt and diff the generated state matrix against reality. Any state the generator produced that production lacks is a bug you just found for free.

Your playbooks & labs

This module's playbooks: pb-02 (Instruction Files That Keep Generated UI on Your Design System), pb-03 (Registry-Grounded Generation), pb-04 (Schema-First Forms), pb-05 (Complex Interactions: AI Scaffolds, You Own the Last 30%), pb-06 (Storybook as the Agent's Visual Verification Loop), pb-07 (Typed API Clients and MSW Mocks from the Schema), and pb-08 (State and Data-Layer Refactors with Characterization Protection). Lab 01 grades your instruction files with an automated on-system lint; Lab 03 is the registry A/B with a comparison memo.

Further Reading

Key Takeaway:

Generators emit the design system they were trained on unless you make yours louder: instruction files state the rules, exemplars show the shape, registry MCP serves the truth, and an off-system lint holds the line in CI. Condition first, generate second, and review only what conditioning can't decide.

This is the free reading view. Open BXUP to track your progress, run the hands-on labs, and prove it with original, exam-pattern assessments.
© Anvi Innovate · BXUP — Be Exponentially Upskilled · BXUP is an independent learning platform, not affiliated with or endorsed by AWS, Microsoft, Google, NVIDIA, IBM, Salesforce, Databricks, Oracle or Anthropic. All trademarks belong to their respective owners. · bxup.in