Skip to content
Back to skills

Add Shadcn Component

ASecurity

Use for /add-shadcn-component <component>. Adds a shadcn component to src/web/components/ui/ with the outline focus, token colours, exact package pins and gallery entry.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 30, 2026
developmentreactnodegitfrontend

Works with

  • cli

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned September 30, 2026

npx -y skills add theyashgupta/dispatch --skill add-shadcn-component --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Add Shadcn Component?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Add Shadcn Component
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/theyashgupta-add-shadcn-component/badge)](https://www.skillsdirectory.com/skills/theyashgupta-add-shadcn-component)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: add-shadcn-component
description: Use for /add-shadcn-component <component>. Adds a shadcn component to src/web/components/ui/ with the outline focus, token colours, exact package pins and gallery entry.
---

# Add a shadcn component

The rules are in `docs/standards/frontend-architecture.md`, in the sections "The only-shadcn rule" and "Shared tiers".

`<component>` is the registry name of the component. Example: `dropdown-menu`.

## Procedure

1. Run the shadcn CLI:

   ```
   env -u NODE_ENV npx shadcn@latest add <component> -y
   ```

2. Run `git status --short`. Record each file that the CLI created or changed.
3. Format the new files. The CLI writes files without semicolons, so `format:check` fails on them before this step.

   ```
   env -u NODE_ENV npx prettier --write <each new file>
   ```

4. Do not write a new primitive by hand. Do not change a generated file, except with the edits in steps 5 to 17 or with a `cva` variant.

## Packages

5. Open `package.json`. The CLI adds packages to `dependencies`, for example `radix-ui`, `cn`, `cmdk` and `sonner`.
   1. Move each web package that the CLI added to `devDependencies`.
   2. Pin each moved package to an exact version. Remove each `^` and `~`.
   3. Do not move `zod` or a server package.
   4. Do not install `next-themes`, `react-hook-form` or `@hookform/resolvers`.
   5. Run `env -u NODE_ENV npm install` to update `package-lock.json`.

## Focus outline

6. In each generated file, replace each of these classes with `focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring`:
   - `focus-visible:ring-*`
   - `focus-visible:border-ring`
   - `ring-offset-*`
   - `aria-invalid:ring-*` and `dark:aria-invalid:ring-*`

   If the class string also has `outline-hidden` or `outline-none`, add `focus-visible:outline-solid`; focus-outline.test.ts enforces it.

7. Keep `aria-invalid:border-destructive`.
8. If an ancestor with `overflow: hidden` cuts the outline, use `focus-visible:outline-offset-0` at that element. Menu and select items use the inset form `focus-visible:-outline-offset-2`.
9. Run `grep -nE '(^|[^a-z-])ring-' <file>` on each generated file. The command must show no line.

## Colours

10. Replace each Tailwind default palette class with a token class. Examples: `text-white` becomes `text-on-accent` or `text-on-danger`, and `bg-black/50` becomes `bg-scrim`.
11. Replace a raw colour variable in a class, for example `hsl(var(--x))`, with `var(--x)`.
12. Open `src/web/styles/globals.css`. Remove each colour value that the CLI added, for example an `oklch()` value.
13. Map each new shadcn colour name to a token that `src/web/styles/tokens.css` defines. Do not add a shadcn name to `tokens.css`.
    1. In the `:root` block of `src/web/styles/globals.css`, add one custom property for the name. Its value is `var()` of the token. Example: `--card: var(--surface-card);`.
    2. In the `@theme inline` block of `src/web/styles/globals.css`, add the colour name. Example: `--color-card: var(--card);`.
    3. `tokens.css` already defines some names. Do not add a `:root` line for these names. Map each one in the `@theme inline` block of `src/web/styles/globals.css`:
       - `accent`: `--color-accent: var(--surface-card-hover);`
       - `destructive`: `--color-destructive: var(--destructive);`
       - `border`: `--color-border: var(--border);`
       - `radius`: `--radius-md: var(--radius);`. The `--radius-sm` and `--radius-lg` tokens in `tokens.css` set the other sizes.
14. If a token class does not exist in the `@theme inline` block of `src/web/styles/globals.css`, add its mapping there. Do not write a colour value.
15. Keep the `@custom-variant dark` line in `src/web/styles/globals.css`.

## Sonner

16. If the component is `sonner`, remove the `next-themes` import from `sonner.tsx`. Give the `Toaster` a `theme` prop that its consumer sets. Do not import a hook from outside `src/web/components/ui/`.

## Gallery

17. Add the component to `src/web/gallery-main.tsx`, in the group of its family. If this file does not exist, skip this step and tell the user.

## Checks

18. Run `env -u NODE_ENV npm run check:static`. It must pass.
19. Tell the user the new files, the moved packages and their versions.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…