Website · Scan a repository · Docs · 62 rules · Sponsor
Shadscan inspects a React shadcn app, scores its UI fundamentals from 0 to 100, and shows the evidence behind every finding. It catches the product details that are easy to postpone: command menus, theme shortcuts, route states, accessible controls, form feedback, metadata, mobile behavior, and more.
The default scan is deterministic and read-only. It does not start the app, edit files, call an AI model, upload source, or require application secrets.
Run Shadscan from the root of a project:
pnpm dlx @shadscan/cliThe project path defaults to the current directory. Pass a path to scan another app:
pnpm dlx @shadscan/cli ../my-shadcn-appUsing npm or Bun:
npx --yes @shadscan/cli
bunx @shadscan/cliCommands resolve to the latest stable release. Prereleases are published
under the next tag (@shadscan/cli@next) for early testing.
Interactive human source audits show progress immediately and keep each completed phase above the final report:
✓ Resolving project
✓ Discovering app structure
✓ Evaluating UI rules
✓ Preparing report
Rendered UI checks use phases specific to browser work:
✓ Resolving UI target
✓ Checking mobile and desktop layouts
✓ Preparing UI report
Both checklists are written to stderr for interactive human output only. JSON,
CI, TERM=dumb, non-TTY stderr, and --no-interactive output stay quiet;
prompt output also stays quiet. Redirecting stdout keeps the report clean while
progress remains on an eligible stderr terminal.
Every interactive scan ends with a short menu — pick with the arrow keys and Enter: copy the agent handoff to your clipboard, print it, launch an installed coding agent, or add a pre-commit score gate. The handoff is highlighted first, so a single Enter grabs it; press Esc to keep just the score.
Your shadscan score: [###############-] 92/100 (Grade A)
shadscan has entered the chat.
Categories:
Foundation: 20/20 (100%)
Interaction: 12.2/20 (61%)
States: 20/20 (100%)
Accessibility: 20/20 (100%)
Forms and Data Entry: 10/10 (100%)
Production Polish: 10/10 (100%)
Missing: command menu has a Cmd/Ctrl+K shortcut
Evidence: No complete mounted Cmd/Ctrl+K command-menu shortcut was found.
Fix: Register a shortcut that prevents the browser default and toggles the menu.
Every report separates:
- Fixes: high-confidence defects with repository-relative evidence.
- Decisions: product choices that should be implemented or explicitly waived.
- Advisories: lower-confidence checks that need rendered or manual verification.
- Not applicable: rules excluded because the relevant UI surface is absent.
# Machine-readable, versioned report
pnpm dlx @shadscan/cli --json
# Paste-ready remediation plan for a coding agent
pnpm dlx @shadscan/cli --prompt
# Explicitly launch an installed agent with the generated plan
pnpm dlx @shadscan/cli --apply --agent codex
# Fail CI when the complete assessed score is below the floor
pnpm dlx @shadscan/cli@0.17.1 --fail-under 80 --no-interactive --no-roast
# Audit one category while investigating a focused area
pnpm dlx @shadscan/cli --category accessibility
# See which workspace packages shadscan found, without scanning
pnpm dlx @shadscan/cli --list-projects
# Scan one package of a monorepo instead of pooling every application
pnpm dlx @shadscan/cli --project apps/web
# Run rendered UI checks at mobile and desktop widths
pnpm dlx @shadscan/cli --check-ui http://localhost:3000
# Include more same-origin routes (the target URL is always checked)
pnpm dlx @shadscan/cli --check-ui http://localhost:3000 --route /dashboard --route /settingsUse --format human, --format json, or --format prompt when output selection
needs to be explicit. Pin an exact package version in CI; unqualified commands
resolve to the latest stable release. Run pnpm dlx @shadscan/cli --help for
every option.
--check-ui is the home for deterministic checks that need a rendered page.
Horizontal overflow is its first check. It opens an already-running local or
deployed app in isolated Chromium pages at these fixed CSS viewports:
- mobile: 320 × 820;
- desktop: 1440 × 1000.
It reports a critical failure if the document has even one CSS pixel of
horizontal overflow, or if the root or body forces a horizontal scrollbar.
Likely culprit selectors are included when Shadscan can identify them. The
target URL is always checked; repeat --route to add up to ten paths beginning
with /. Routes cannot contain a query string or fragment. When the initial
request returns a narrowly validated server-side canonical redirect, Shadscan
can follow a conventional two-label apex-to-www or www-to-apex host change
and an HTTP-to-HTTPS upgrade. It pins the resulting origin for every additional
route. For multi-label public suffixes, pass the canonical origin directly. Other
cross-origin redirects, HTTPS downgrades, and client-side cross-origin
navigations remain blocked. Reports use the resolved origin as their target;
human output also identifies the originally requested origin when it changed.
This rendered UI suite is separate from the default static source audit. Its
overflow check does not add a rule, score, or grade, and it leaves the 62-rule
catalog and existing mobile-overflow-absent advisory unchanged. Shadscan does
not start or build the target app, so start it yourself first or pass a deployed
URL. The command can run outside a project directory.
# Human report
pnpm dlx @shadscan/cli --check-ui http://localhost:3000
# Versioned JSON for automation
pnpm dlx @shadscan/cli --check-ui https://preview.example.com --jsonA clean result exits 0. Detected overflow exits 1 after writing the
complete human or JSON report to stdout. Browser, target, timeout, and argument
errors exit 1, leave stdout empty, and write the error to stderr. If no
supported Chromium installation is available, run:
pnpm dlx playwright-core@1.61.1 install chromiumRendered UI checks perform GET navigations and execute the target's page JavaScript in fresh isolated browser contexts. It reads no project source, invokes no package scripts, and saves no page data. This focused mode is available only in the local CLI, not through MCP, the GitHub Action, hosted API, or web scanner.
The repository doubles as a composite GitHub Action that runs the CLI, writes the score to the job summary, enforces an optional score floor, and can create or update a tracked issue containing the findings and a paste-ready AI-agent remediation handoff.
name: shadscan
on:
push:
branches: [main]
permissions:
contents: read
issues: write # only needed with create-issue
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: TheOrcDev/shadscan@main
with:
path: .
version: 0.17.1 # pin an exact CLI version in CI
fail-under: "80"
create-issue: "true"Inputs: path, version, category, fail-under, create-issue,
issue-label, and github-token. Outputs: score, grade, and
report-path (the machine-readable JSON report). With create-issue, the
action keeps a single open issue per label up to date instead of filing a new
issue on every run, and the issue body embeds the same --prompt handoff you
would generate locally — ready to paste into a coding agent.
--prompt turns the same deterministic report into a neutral, paste-ready plan
for another coding agent. The handoff includes:
- prioritized work items grouped as
fix,decide, orverify; - rule IDs, evidence, suggested fixes, and acceptance criteria;
- detected framework, package manager, and source-coverage context;
- repository-owned verification commands that the agent must inspect first;
- the exact pinned Shadscan command to rescan after the work.
--apply is an explicit local action. It validates an installed Claude Code,
Codex CLI, or Grok Build executable before launching it. Shadscan itself still
does not make an AI request; the selected external agent follows its own
provider and approval model.
shadscan mcp serves the same deterministic audit over the Model Context
Protocol on stdio, so coding agents can query results as typed tool calls
instead of parsing output:
claude mcp add shadscan -- npx -y @shadscan/cli mcpThree read-only tools: scan (score plus filterable actionables — by
category, severity, or workspace package), list_projects (workspace
packages with their application-or-library classification), and
explain_rule (what one rule checks and where it applies). Every call
re-scans the current file state — results are never cached — and every
response carries the engine, ruleset, and schema versions. The server scans
inside the roots it was started with and nothing else, and it never writes
files. Details and per-client setup live in docs/mcp.md.
The bundled ruleset contains 62 deterministic checks across six weighted categories.
| Category | Examples |
|---|---|
| Foundation | shadcn config, mounted theme provider, metadata, favicon, not-found and error boundaries |
| Interaction | dark-mode and command-menu shortcuts, safe global hotkeys, mobile navigation, focus visibility |
| States | loading and Suspense fallbacks, empty states, retryable errors, pending actions, mounted toasts |
| Accessibility | names and labels, semantic controls, alt text, landmarks, live regions, keyboard and focus behavior |
| Forms and Data Entry | validation, rendered field errors, error associations, legends, button types, autocomplete |
| Production Polish | complete metadata, social previews, Button icon spacing, responsive shells, SEO files, mobile overflow |
See the generated rule catalog for every rule ID, confidence level, score behavior, and supported adapter.
Raw rule points are normalized within each weighted category to produce the 100-point score. High- and medium-confidence failures can reduce the score. Low-confidence checks stay visible as score-neutral advisories instead of pretending static analysis can prove rendered behavior.
Rules only run where they apply. Shadscan supports Next.js App Router, Pages Router, hybrid Next.js projects, React Router framework mode, TanStack Start, Laravel with Inertia and React, Astro with React islands, Vite React, and generic React applications.
Run shadscan at a workspace root and it audits every React application it
finds, pooling their findings into one score. The report lists each package
with its own score so the pooled number is explicable, and --list-projects
prints that list without scanning.
Packages are classified as applications or libraries. A library — a React package with no application entry point — is scanned and reported, but its findings do not count toward the score: it has no document shell, so it would fail rules about page titles and favicons that it should never satisfy, and pooling those would punish you for owning a design system. Packages that shadscan cannot audit at all, such as one that does not declare React, are listed as skipped with the reason.
Workspaces are found by walking the tree for package.json files, so pnpm,
npm, yarn, bun, Turborepo, Nx and Lerna all work without configuration. A
workspace containing a single application is scanned exactly as before, so the
common "app at the root plus shared packages" layout keeps its existing score.
Use --project <path> to scan one package on its own.
The web scanner audits a public GitHub repository without installing the CLI or exposing an API key to the browser. GitHub access, extraction, rate limiting, and scanning stay on the server.
For agent and service integrations, Shadscan also exposes a versioned hosted API for public GitHub repositories and sanitized gzip tar snapshots.
- Pinned agent instructions
- OpenAPI 3.1 contract
- Hosted API setup and security
- Web scanner architecture and deployment
The hosted surfaces are opt-in and have separate source-handling contracts from the local CLI.
Repository development uses Node.js 24 and pnpm 11.15.1. The published CLI has a Node.js 18 compatibility floor.
pnpm install
pnpm cli:test
pnpm test:api
pnpm test:web
pnpm exec playwright install chromium
pnpm test:e2e
pnpm docs:check
pnpm check
pnpm typecheck
pnpm buildThe product site and its own dogfood target live at the repository root. The
published CLI lives in packages/cli.
| Document | Purpose |
|---|---|
| Contributing guide | Development setup, repository map, tests, documentation, and pull requests |
| CLI contract | Invocation, output, exit status, stability, privacy, and security guarantees |
| Rule catalog | All bundled checks and their scoring behavior |
| Hosted API | Authentication, request formats, deployment, and source handling |
| Web scanner | Public scan flow, limits, runtime boundaries, and verification |
| Release guide | Candidate, stable, trusted-publishing, and recovery procedures |
| Security policy | Supported versions and vulnerability reporting |
The Shadscan CLI is available under the MIT License. The header and badges are rendered by shieldcn, a shadcn-styled badge and README graphics service.