mcpField
S
shadcn-detection

shadcn-detection

github.com/fusengineDevelopment3441 installsUpdated 2w ago
Repository

About shadcn-detection

shadcn-detection is a project-analysis skill for developers working with shadcn/ui. It identifies the component base—Base UI, Radix, React Aria, mixed, or none—using CLI output and repository signals before component work.

Key features

  1. 01CLI-based base identification
  2. 02Weighted scan of five signals
  3. 03Dependency and config inspection
  4. 04Import and data-attribute analysis
  5. 05Mixed-base migration detection
  6. 06Package manager detection

Use cases

  1. 01Checking a project's shadcn/ui base
  2. 02Choosing compatible component patterns
  3. 03Identifying mixed-base migrations

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/fusengine/agents --skill shadcn-detection

After installing, type/shadcn-detectionin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
baseui-patterns.md
detection-algorithm.md
radix-patterns.md
references/templates/
detection-script.md

Details

From the project README
Detects which of the three shadcn/ui component bases a project uses: Base UI (`base`, default for new projects since July 2026), Radix (`radix`, fully supported) or React Aria (`aria`, added July 2026). Authoritative signal first (`shadcn info --json` -> `config.base`), then a 5-signal weighted scan: package.json dependencies, components.json's style prefix, source import patterns, data-attribute conventions (`data-state` vs `data-open` vs `data-entering`), and the lockfile-detected package manager.

Produces a Base UI / Radix / React Aria / Mixed (migration needed) / None (fresh setup) verdict that gates every downstream shadcn component or migration task.

shadcn Detection

Agent Workflow (MANDATORY)

Before detection, spawn agents in parallel, one Agent call each with a name:

  1. fuse-ai-pilot:explore-codebase - Scan project structure
  2. fuse-ai-pilot:research-expert - Verify latest primitive patterns

After: Use results to configure component workflow.


Overview

FeatureDescription
CLI probe (authoritative){runner} shadcn@latest info --json -> .config.base = base | radix | aria (plus .config.style, .components, .links)
Package scanDetect @base-ui/react, radix-ui / @radix-ui/*, react-aria-components
Config checkAnalyze components.json style prefix (base-*, radix-*/new-york, aria-*)
Import analysisScan source for import patterns
Attribute scandata-state= (Radix) vs data-open (Base UI) vs data-entering/data-placement (React Aria)
Package managerDetect bun/npm/pnpm/yarn via lockfile
BasePackageStyle prefixCompositionDocs
Base UI (default)@base-ui/reactbase-*render prop/docs/components/base/<name>
Radixradix-ui (legacy @radix-ui/react-*)radix-*, legacy new-yorkasChild/docs/components/radix/<name>
React Ariareact-aria-componentsaria-*Trigger wrapper (DialogTrigger > Button + Dialog), slot, onPress/docs/components/aria/<name>

Known cross-base dependencies (NOT a mixed project): radix-* Combobox imports @base-ui/react (Radix has no Combobox); Questionnaire and MessageScroller import @shadcn/react on every base; every current component imports cn from the cn package.


Critical Rules

  1. ALWAYS run detection before any component work
  2. CHECK all 5 signals for maximum accuracy
  3. HANDLE mixed state as migration case, never ignore
  4. CACHE result for session duration, no re-detection needed
  5. DETECT package manager via lockfile priority order

Architecture

project/
├── package.json            # Step 1: deps scan
├── components.json         # Step 2: style field
├── bun.lock|bun.lockb|pnpm-lock.yaml|yarn.lock|package-lock.json  # Step 5: PM
└── src/|components/|app/   # Step 3-4: imports + attrs

→ See detection-script.md for complete example


5-Step Detection Algorithm

Step 0: if components.json exists, {runner} shadcn@latest info --json gives the base directly; the weighted scan below confirms it and catches mixed projects.

StepSignalWeight
1package.json deps (@base-ui/react, radix-ui / @radix-ui/*, react-aria-components)40%
2components.json style prefix (base-*, radix-*/new-york, aria-*)20%
3Import patterns in source files25%
4Data attributes (data-state= / data-open / data-entering)15%
5Package manager (lockfile → bunx/npx/pnpm dlx/yarn dlx)-

Decision Table

Each base gets its own score (0-100).

ScoresResultAction
Only Base UI >50Base UIUse Base UI patterns (render)
Only Radix >50RadixUse Radix patterns (asChild)
Only React Aria >50React AriaUse React Aria patterns (trigger wrapper, onPress)
Two or more >0 (after discounting the known cross-base deps above)MixedMigration needed
All 0NoneFresh setup: init defaults to Base UI; pass -b radix or -b aria to choose

Best Practices

DO
  • Run detection BEFORE any component work
  • Check all 5 signals for accuracy
  • Handle "mixed" state as migration case
DON'T
  • Assume Radix (or Base UI, the new default) without checking
  • Skip components.json analysis
  • Ignore data-attribute signals
  • Count @base-ui/react from a Radix-style Combobox as a mixed project

Reference Guide

Concepts
TopicReferenceWhen to Consult
Radix Patternsradix-patterns.mdIdentifying Radix UI signals
Base UI Patternsbaseui-patterns.mdIdentifying Base UI signals
Algorithmdetection-algorithm.mdUnderstanding scoring logic, React Aria signals
Templates
TemplateWhen to Use
detection-script.mdRunning detection on a project

Comments

Markdown supported