Skip to content
Back to skills

Component Layer

ASecurity

This skill should be used when the user asks to 'create a component', 'add a button', 'build a card', 'add UI element', or 'create a feature component'. Provides guidance for React components using shadcn/ui, Radix primitives, and CVA patterns in components/**/*.tsx.

  • 666 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added February 8, 2026
developmenttypescriptbashreactnode

Works with

  • cli

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add majiayu000/claude-skill-registry --skill component-layer --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Component Layer?

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

Security grade badge for Component Layer
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-component-layer/badge)](https://www.skillsdirectory.com/skills/majiayu000-component-layer)

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: component-layer
description: "This skill should be used when the user asks to 'create a component', 'add a button', 'build a card', 'add UI element', or 'create a feature component'. Provides guidance for React components using shadcn/ui, Radix primitives, and CVA patterns in components/**/*.tsx."
---

# Component Layer Skill

## Scope

- `components/ui/*.tsx` - shadcn/ui base components (Radix primitives)
- `components/features/*.tsx` - Feature-specific components
- `components/shared/*.tsx` - Reusable shared components
- `components/layout/*.tsx` - Layout components
- `components/mdx/*.tsx` - MDX-specific components
- `components/providers/*.tsx` - Context providers

## Decision Tree

### Creating a new UI primitive?

1. **Check if shadcn/ui has it**: Visit ui.shadcn.com first
2. **If available**: Use `npx shadcn@latest add <component>`
3. **If custom**: Create in `components/ui/` following CVA pattern
4. **Export from component file** (no barrel exports needed)

### Creating a feature component?

1. **Create in `components/features/`**
2. **Name descriptively**: `contact-form.tsx`, `articles-list.tsx`
3. **Import UI primitives** from `@/components/ui/`
4. **Use server components** by default (no "use client" unless needed)

### Creating a shared/reusable component?

1. **Create in `components/shared/`**
2. **Keep it generic** - no feature-specific logic
3. **Props interface** with clear types
4. **Consider composition** over configuration

### Adding client interactivity?

1. **Add `"use client"` directive** at top of file
2. **Keep client boundary small** - extract client parts
3. **Prefer server components** when possible

## Quick Templates

### UI Component with CVA (shadcn/ui pattern)

```tsx
import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";
import { cn } from "@/lib/utils";

const componentVariants = cva(
  "base-classes-here",
  {
    variants: {
      variant: {
        default: "variant-default-classes",
        secondary: "variant-secondary-classes",
      },
      size: {
        default: "size-default-classes",
        sm: "size-sm-classes",
        lg: "size-lg-classes",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
);

export interface ComponentProps
  extends React.HTMLAttributes<HTMLDivElement>,
    VariantProps<typeof componentVariants> {}

const Component = React.forwardRef<HTMLDivElement, ComponentProps>(
  ({ className, variant, size, ...props }, ref) => {
    return (
      <div
        ref={ref}
        className={cn(componentVariants({ variant, size, className }))}
        {...props}
      />
    );
  }
);
Component.displayName = "Component";

export { Component, componentVariants };
```

### Feature Component (Server)

```tsx
import { ComponentName } from "@/components/ui/component-name";

interface FeatureProps {
  title: string;
  items: Array<{ id: string; name: string }>;
}

export function FeatureName({ title, items }: FeatureProps) {
  return (
    <section>
      <h2>{title}</h2>
      <ul>
        {items.map((item) => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </section>
  );
}
```

### Client Component

```tsx
"use client";

import { useState } from "react";
import { Button } from "@/components/ui/button";

interface InteractiveProps {
  initialValue: string;
}

export function InteractiveComponent({ initialValue }: InteractiveProps) {
  const [value, setValue] = useState(initialValue);

  return (
    <div>
      <span>{value}</span>
      <Button onClick={() => setValue("clicked")}>Click me</Button>
    </div>
  );
}
```

### Layout Component

```tsx
import { cn } from "@/lib/utils";

interface ContainerProps extends React.HTMLAttributes<HTMLDivElement> {
  children: React.ReactNode;
}

export function Container({ className, children, ...props }: ContainerProps) {
  return (
    <div className={cn("mx-auto max-w-7xl px-4", className)} {...props}>
      {children}
    </div>
  );
}
```

## Mistakes

- ❌ `"use client"` when not needed (adds to bundle)
- ❌ Missing `cn()` utility for className merging
- ❌ Missing `displayName` on forwardRef components
- ❌ Not extending HTML element attributes for proper typing
- ❌ Wrong directory (ui vs features vs shared)
- ❌ Inline styles instead of Tailwind classes

## Validation

After changes, run:
```bash
.claude/skills/component-layer/scripts/validate-component-patterns.sh <file>
pnpm typecheck  # Verify TypeScript
pnpm check      # Biome lint/format
```

## Directory Structure

```
components/
├── ui/           # shadcn/ui primitives (button, card, etc.)
├── features/     # Feature-specific (contact-form, articles-list)
├── shared/       # Reusable across features (avatar, social-icons)
├── layout/       # Layout components (container, header, footer)
├── mdx/          # MDX rendering components (code, code-tabs)
└── providers/    # Context providers (theme, posthog)
```

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…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.