How-toFrontend

How to Audit an Existing Tailwind and shadcn/ui Screen

Find ownership leaks, raw colors, dynamic classes, and risky shadcn updates, then refactor them safely.

Updated Verified SourceEdit this page

When to use this guide

Use this how-to guide when a Tailwind and shadcn/ui screen has unclear change locations or accumulating consumer overrides.

Fix the goal and scope

Limit the audit to one feature or one change flow. Do not turn it into a repository-wide class-reduction exercise. The output is an owner-classified issue list, edits within those owners, and verification evidence.

  1. Collect live context

    pnpm exec shadcn info --json -c apps/web
    rg -n "@theme|@source|@custom-variant" packages/ui apps/web
    rg -n "@base-ui/react|#[0-9a-fA-F]{3,8}|(?:bg|text|border)-(?:slate|gray|zinc|neutral)-" apps/web

    Read DESIGN_SYSTEM.md, the nearest AGENTS.md, components.json, theme providers, token adapters, the cn implementation, and the target primitives.

  2. Assign one owner to every issue

    ObservationOwnerDefault action
    Light and dark values differ by call sitetheme providerunify the actual value of a semantic role
    The same intent repeats padding and color overridesshared primitiveuse or add a closed variant
    Shared source contains domain copy and stateproduct compositionmove it into the app
    A one-off grid formula is presentpage or featurekeep it at the call site
    Vendor markup requires !importantscoped integration CSSrecord version and removal condition

    Split changes with two owners and explain their dependency direction.

  3. Correct high-risk patterns first

    Prioritize dynamic class fragments, nonexistent semantic utilities, direct headless imports from the app, raw colors, and repeated internal-style overrides.

    // Avoid
    <div className={`bg-${tone}-600`} />
    
    // Prefer
    const toneClass = {
      default: "bg-primary text-primary-foreground",
      danger: "bg-destructive text-destructive-foreground",
    } as const;

    Do not convert every layout formula or renderer literal into a token. Keep exceptions whose owners and reasons to change are distinct in an inventory.

  4. Preview shadcn source changes

    pnpm exec shadcn docs button -c apps/web
    pnpm exec shadcn add button --dry-run -c apps/web
    pnpm exec shadcn add button --diff button.tsx -c apps/web

    Separate upstream accessibility and API changes from local variants, then merge only what is needed. Do not make --overwrite the default for a locally modified layer.

  5. Verify in proportion to the owner

    pnpm run fmt:check
    pnpm run lint
    pnpm --filter @jongminchung/web run typecheck
    pnpm --filter @jongminchung/web run test
    pnpm --filter @jongminchung/web run build

    For primitive behavior, verify keyboard use, focus, accessible names, and dismissal. For tokens, verify every consumer in light and dark modes.

Report by owner

  • State which decisions moved to a theme, primitive, composition, or page.
  • Name the reused variant and semantic token.
  • Record the commands run and their results.
  • Give every retained exception an owner, reason, scope, and removal condition.

Completion criteria

  • No new dynamic class fragments or consumer raw colors remain.
  • Apps do not bypass the shared accessibility boundary.
  • Repeated overrides converge into a variant or product composition.
  • components.json aliases and Tailwind @source entries resolve to real paths.
  • Interaction and visual results match the scope of the change.