Master React, Vue, and Svelte component patterns including

Web component design

by wshobson · MIT license · ★ 39,857 on GitHub · updated Sep 21

Web component design cover

Master React, Vue, and Svelte component patterns including CSS-in-JS, composition strategies, and reusable component architecture. Use when building UI component libraries, designing component APIs, or implementing frontend design systems.

---
name: web-component-design
description: Master React, Vue, and Svelte component patterns including CSS-in-JS, composition strategies, and reusable component architecture. Use when building UI component libraries, designing component APIs, or implementing frontend design systems.
---

# Web Component Design

Build reusable, maintainable UI components using modern frameworks with clean composition patterns and styling approaches.

## When to Use This Skill

- Designing reusable component libraries or design systems
- Implementing complex component composition patterns
- Choosing and applying CSS-in-JS solutions
- Building accessible, responsive UI components
- Creating consistent component APIs across a codebase
- Refactoring legacy components into modern patterns
- Implementing compound components or render props

Overview

Build reusable, maintainable UI components using modern frameworks with clean composition patterns and styling approaches.

Manual install (npx, ZIP)
Claude Codenpx skills add wshobson/agents --skill web-component-design -g -a claude-code
Claude Code (manual)mkdir -p ~/.claude/skills && curl -sL https://codeload.github.com/wshobson/agents/tar.gz/4236bb91f839 \ | tar -xz -C ~/.claude/skills --strip-components=4 agents-4236bb91f839/plugins/ui-design/skills/web-component-design
Windows (PowerShell)New-Item -ItemType Directory -Force "$HOME\.claude\skills" | Out-Null; Invoke-WebRequest "https://m.agentalley.io/zip/ebfc4ce3a803a30f3406/web-component-design.zip" -OutFile "$env:TEMP\web-component-design.zip"; Expand-Archive "$env:TEMP\web-component-design.zip" -DestinationPath "$HOME\.claude\skills" -Force
Claude.ai / desktopDownload the ZIP and upload it under Settings → Capabilities → Skills.
Codex, Cursor, other agentsPoint them at SKILL.md. The other files are plain text.

Connects with Agent Alley MCP · agentalley.io/mcp

Files included

  • SKILL.md7.3 KB
  • references/3 files · 37.5 KB
Read the files here
wshobson/4236bb94 files
SKILL.md
Show the full text272 lines

Web Component Design

Build reusable, maintainable UI components using modern frameworks with clean composition patterns and styling approaches.

When to Use This Skill

  • Designing reusable component libraries or design systems
  • Implementing complex component composition patterns
  • Choosing and applying CSS-in-JS solutions
  • Building accessible, responsive UI components
  • Creating consistent component APIs across a codebase
  • Refactoring legacy components into modern patterns
  • Implementing compound components or render props

Core Concepts

1. Component Composition Patterns

Compound Components: Related components that work together

// Usage
<Select value={value} onChange={setValue}>
  <Select.Trigger>Choose option</Select.Trigger>
  <Select.Options>
    <Select.Option value="a">Option A</Select.Option>
    <Select.Option value="b">Option B</Select.Option>
  </Select.Options>
</Select>

Render Props: Delegate rendering to parent

<DataFetcher url="/api/users">
  {({ data, loading, error }) =>
    loading ? <Spinner /> : <UserList users={data} />
  }
</DataFetcher>

Slots (Vue/Svelte): Named content injection points

<template>
  <Card>
    <template #header>Title</template>
    <template #content>Body text</template>
    <template #footer><Button>Action</Button></template>
  </Card>
</template>
2. CSS-in-JS Approaches
Solution Approach Best For
Tailwind CSS Utility classes Rapid prototyping, design systems
CSS Modules Scoped CSS files Existing CSS, gradual adoption
styled-components Template literals React, dynamic styling
Emotion Object/template styles Flexible, SSR-friendly
Vanilla Extract Zero-runtime Performance-critical apps
3. Component API Design
interface ButtonProps {
  variant?: "primary" | "secondary" | "ghost";
  size?: "sm" | "md" | "lg";
  isLoading?: boolean;
  isDisabled?: boolean;
  leftIcon?: React.ReactNode;
  rightIcon?: React.ReactNode;
  children: React.ReactNode;
  onClick?: () => void;
}

Principles:

  • Use semantic prop names (isLoading vs loading)
  • Provide sensible defaults
  • Support composition via children
  • Allow style overrides via className or style

Quick Start: React Component with Tailwind

import { forwardRef, type ComponentPropsWithoutRef } from "react";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";

const buttonVariants = cva(
  "inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50",
  {
    variants: {
      variant: {
        primary: "bg-blue-600 text-white hover:bg-blue-700",
        secondary: "bg-gray-100 text-gray-900 hover:bg-gray-200",
        ghost: "hover:bg-gray-100 hover:text-gray-900",
      },
      size: {
        sm: "h-8 px-3 text-sm",
        md: "h-10 px-4 text-sm",
        lg: "h-12 px-6 text-base",
      },
    },
    defaultVariants: {
      variant: "primary",
      size: "md",
    },
  },
);

interface ButtonProps
  extends
    ComponentPropsWithoutRef<"button">,
    VariantProps<typeof buttonVariants> {
  isLoading?: boolean;
}

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant, size, isLoading, children, ...props }, ref) => (
    <button
      ref={ref}
      className={cn(buttonVariants({ variant, size }), className)}
      disabled={isLoading || props.disabled}
      {...props}
    >
      {isLoading && <Spinner className="mr-2 h-4 w-4" />}
      {children}
    </button>
  ),
);
Button.displayName = "Button";

Framework Patterns

React: Compound Components
import { createContext, useContext, useState, type ReactNode } from "react";

interface AccordionContextValue {
  openItems: Set<string>;
  toggle: (id: string) => void;
}

const AccordionContext = createContext<AccordionContextValue | null>(null);

function useAccordion() {
  const context = useContext(AccordionContext);
  if (!context) throw new Error("Must be used within Accordion");
  return context;
}

export function Accordion({ children }: { children: ReactNode }) {
  const [openItems, setOpenItems] = useState<Set<string>>(new Set());

  const toggle = (id: string) => {
    setOpenItems((prev) => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  };

  return (
    <AccordionContext.Provider value={{ openItems, toggle }}>
      <div className="divide-y">{children}</div>
    </AccordionContext.Provider>
  );
}

Accordion.Item = function AccordionItem({
  id,
  title,
  children,
}: {
  id: string;
  title: string;
  children: ReactNode;
}) {
  const { openItems, toggle } = useAccordion();
  const isOpen = openItems.has(id);

  return (
    <div>
      <button onClick={() => toggle(id)} className="w-full text-left py-3">
        {title}
      </button>
      {isOpen && <div className="pb-3">{children}</div>}
    </div>
  );
};
Vue 3: Composables
<script setup lang="ts">
import { ref, computed, provide, inject, type InjectionKey } from "vue";

interface TabsContext {
  activeTab: Ref<string>;
  setActive: (id: string) => void;
}

const TabsKey: InjectionKey<TabsContext> = Symbol("tabs");

// Parent component
const activeTab = ref("tab-1");
provide(TabsKey, {
  activeTab,
  setActive: (id: string) => {
    activeTab.value = id;
  },
});

// Child component usage
const tabs = inject(TabsKey);
const isActive = computed(() => tabs?.activeTab.value === props.id);
</script>
Svelte 5: Runes
<script lang="ts">
  interface Props {
    variant?: 'primary' | 'secondary';
    size?: 'sm' | 'md' | 'lg';
    onclick?: () => void;
    children: import('svelte').Snippet;
  }

  let { variant = 'primary', size = 'md', onclick, children }: Props = $props();

  const classes = $derived(
    `btn btn-${variant} btn-${size}`
  );
</script>

<button class={classes} {onclick}>
  {@render children()}
</button>

Best Practices

  1. Single Responsibility: Each component does one thing well
  2. Prop Drilling Prevention: Use context for deeply nested data
  3. Accessible by Default: Include ARIA attributes, keyboard support
  4. Controlled vs Uncontrolled: Support both patterns when appropriate
  5. Forward Refs: Allow parent access to DOM nodes
  6. Memoization: Use React.memo, useMemo for expensive renders
  7. Error Boundaries: Wrap components that may fail

Common Issues

  • Prop Explosion: Too many props - consider composition instead
  • Style Conflicts: Use scoped styles or CSS Modules
  • Re-render Cascades: Profile with React DevTools, memo appropriately
  • Accessibility Gaps: Test with screen readers and keyboard navigation
  • Bundle Size: Tree-shake unused component variants
1---
2name: web-component-design
3description: Master React, Vue, and Svelte component patterns including CSS-in-JS, composition strategies, and reusable component architecture. Use when building UI component libraries, designing component APIs, or implementing frontend design systems.
4---
5 
6# Web Component Design
7 
8Build reusable, maintainable UI components using modern frameworks with clean composition patterns and styling approaches.
9 
10## When to Use This Skill
11 
12- Designing reusable component libraries or design systems
13- Implementing complex component composition patterns
14- Choosing and applying CSS-in-JS solutions
15- Building accessible, responsive UI components
16- Creating consistent component APIs across a codebase
17- Refactoring legacy components into modern patterns
18- Implementing compound components or render props
19 
20## Core Concepts
21 
22### 1. Component Composition Patterns
23 
24**Compound Components**: Related components that work together
25 
26```tsx
27// Usage
28<Select value={value} onChange={setValue}>
29 <Select.Trigger>Choose option</Select.Trigger>
30 <Select.Options>
31 <Select.Option value="a">Option A</Select.Option>
32 <Select.Option value="b">Option B</Select.Option>
33 </Select.Options>
34</Select>
35```
36 
37**Render Props**: Delegate rendering to parent
38 
39```tsx
40<DataFetcher url="/api/users">
41 {({ data, loading, error }) =>
42 loading ? <Spinner /> : <UserList users={data} />
43 }
44</DataFetcher>
45```
46 
47**Slots (Vue/Svelte)**: Named content injection points
48 
49```vue
50<template>
51 <Card>
52 <template #header>Title</template>
53 <template #content>Body text</template>
54 <template #footer><Button>Action</Button></template>
55 </Card>
56</template>
57```
58 
59### 2. CSS-in-JS Approaches
60 
61| Solution | Approach | Best For |
62| --------------------- | ---------------------- | --------------------------------- |
63| **Tailwind CSS** | Utility classes | Rapid prototyping, design systems |
64| **CSS Modules** | Scoped CSS files | Existing CSS, gradual adoption |
65| **styled-components** | Template literals | React, dynamic styling |
66| **Emotion** | Object/template styles | Flexible, SSR-friendly |
67| **Vanilla Extract** | Zero-runtime | Performance-critical apps |
68 
69### 3. Component API Design
70 
71```tsx
72interface ButtonProps {
73 variant?: "primary" | "secondary" | "ghost";
74 size?: "sm" | "md" | "lg";
75 isLoading?: boolean;
76 isDisabled?: boolean;
77 leftIcon?: React.ReactNode;
78 rightIcon?: React.ReactNode;
79 children: React.ReactNode;
80 onClick?: () => void;
81}
82```
83 
84**Principles**:
85 
86- Use semantic prop names (`isLoading` vs `loading`)
87- Provide sensible defaults
88- Support composition via `children`
89- Allow style overrides via `className` or `style`
90 
91## Quick Start: React Component with Tailwind
92 
93```tsx
94import { forwardRef, type ComponentPropsWithoutRef } from "react";
95import { cva, type VariantProps } from "class-variance-authority";
96import { cn } from "@/lib/utils";
97 
98const buttonVariants = cva(
99 "inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50",
100 {
101 variants: {
102 variant: {
103 primary: "bg-blue-600 text-white hover:bg-blue-700",
104 secondary: "bg-gray-100 text-gray-900 hover:bg-gray-200",
105 ghost: "hover:bg-gray-100 hover:text-gray-900",
106 },
107 size: {
108 sm: "h-8 px-3 text-sm",
109 md: "h-10 px-4 text-sm",
110 lg: "h-12 px-6 text-base",
111 },
112 },
113 defaultVariants: {
114 variant: "primary",
115 size: "md",
116 },
117 },
118);
119 
120interface ButtonProps
121 extends
122 ComponentPropsWithoutRef<"button">,
123 VariantProps<typeof buttonVariants> {
124 isLoading?: boolean;
125}
126 
127export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
128 ({ className, variant, size, isLoading, children, ...props }, ref) => (
129 <button
130 ref={ref}
131 className={cn(buttonVariants({ variant, size }), className)}
132 disabled={isLoading || props.disabled}
133 {...props}
134 >
135 {isLoading && <Spinner className="mr-2 h-4 w-4" />}
136 {children}
137 </button>
138 ),
139);
140Button.displayName = "Button";
141```
142 
143## Framework Patterns
144 
145### React: Compound Components
146 
147```tsx
148import { createContext, useContext, useState, type ReactNode } from "react";
149 
150interface AccordionContextValue {
151 openItems: Set<string>;
152 toggle: (id: string) => void;
153}
154 
155const AccordionContext = createContext<AccordionContextValue | null>(null);
156 
157function useAccordion() {
158 const context = useContext(AccordionContext);
159 if (!context) throw new Error("Must be used within Accordion");
160 return context;
161}
162 
163export function Accordion({ children }: { children: ReactNode }) {
164 const [openItems, setOpenItems] = useState<Set<string>>(new Set());
165 
166 const toggle = (id: string) => {
167 setOpenItems((prev) => {
168 const next = new Set(prev);
169 next.has(id) ? next.delete(id) : next.add(id);
170 return next;
171 });
172 };
173 
174 return (
175 <AccordionContext.Provider value={{ openItems, toggle }}>
176 <div className="divide-y">{children}</div>
177 </AccordionContext.Provider>
178 );
179}
180 
181Accordion.Item = function AccordionItem({
182 id,
183 title,
184 children,
185}: {
186 id: string;
187 title: string;
188 children: ReactNode;
189}) {
190 const { openItems, toggle } = useAccordion();
191 const isOpen = openItems.has(id);
192 
193 return (
194 <div>
195 <button onClick={() => toggle(id)} className="w-full text-left py-3">
196 {title}
197 </button>
198 {isOpen && <div className="pb-3">{children}</div>}
199 </div>
200 );
201};
202```
203 
204### Vue 3: Composables
205 
206```vue
207<script setup lang="ts">
208import { ref, computed, provide, inject, type InjectionKey } from "vue";
209 
210interface TabsContext {
211 activeTab: Ref<string>;
212 setActive: (id: string) => void;
213}
214 
215const TabsKey: InjectionKey<TabsContext> = Symbol("tabs");
216 
217// Parent component
218const activeTab = ref("tab-1");
219provide(TabsKey, {
220 activeTab,
221 setActive: (id: string) => {
222 activeTab.value = id;
223 },
224});
225 
226// Child component usage
227const tabs = inject(TabsKey);
228const isActive = computed(() => tabs?.activeTab.value === props.id);
229</script>
230```
231 
232### Svelte 5: Runes
233 
234```svelte
235<script lang="ts">
236 interface Props {
237 variant?: 'primary' | 'secondary';
238 size?: 'sm' | 'md' | 'lg';
239 onclick?: () => void;
240 children: import('svelte').Snippet;
241 }
242 
243 let { variant = 'primary', size = 'md', onclick, children }: Props = $props();
244 
245 const classes = $derived(
246 `btn btn-${variant} btn-${size}`
247 );
248</script>
249 
250<button class={classes} {onclick}>
251 {@render children()}
252</button>
253```
254 
255## Best Practices
256 
2571. **Single Responsibility**: Each component does one thing well
2582. **Prop Drilling Prevention**: Use context for deeply nested data
2593. **Accessible by Default**: Include ARIA attributes, keyboard support
2604. **Controlled vs Uncontrolled**: Support both patterns when appropriate
2615. **Forward Refs**: Allow parent access to DOM nodes
2626. **Memoization**: Use `React.memo`, `useMemo` for expensive renders
2637. **Error Boundaries**: Wrap components that may fail
264 
265## Common Issues
266 
267- **Prop Explosion**: Too many props - consider composition instead
268- **Style Conflicts**: Use scoped styles or CSS Modules
269- **Re-render Cascades**: Profile with React DevTools, memo appropriately
270- **Accessibility Gaps**: Test with screen readers and keyboard navigation
271- **Bundle Size**: Tree-shake unused component variants
272 
View all files on GitHub →

Details

Updated
Sep 21, 2026
License
MIT
Stars on the repo
★ 39,857
Checked
Source
wshobson/agents ↗
Creator
wshobson · 179 listings
View creator

Similar skills

See all →
SkillManages shadcn components and projectsshadcn/uishadcn-ui/ui · by shadcn-uiManages shadcn components and projects — adding, searching, fixing, debugging, styling, and composing UI, including chat interfaces. Provides project context, component docs, and usage examples. Applies when working with shadcn/ui, component registries, presets, --preset codes, or any project with a components.json file. Also triggers for "shadcn init", "create an app with --preset", or "switch to --preset".★ 124k GitHub starsSkillWrite agent code, build an agent with ADK, add a toolADK Code Referencegoogle/agents-cli · by googleThis skill should be used when the user wants to "write agent code", build an agent with ADK", "add a tool", "create a callback", "define an agent", use state management" — in a project that needs ADK (Agent Development Kit) API patterns and code examples. It provides a quick reference for agent types, tool definitions, orchestration patterns, callbacks, state management, the graph Workflow API, and reference recipes to study. Do NOT use for scaffolding (use google-agents-cli-scaffold) or deployment (use google-agents-cli-deploy).★ 6k GitHub starsSkillOpen and collaboratively edit a running local app in DesignVisual editBuilderIO/skills · by BuilderIOOpen and collaboratively edit a running local app in Design, with shared fallback previews and source handoff. Use when the user asks to inspect, share, or edit a real local app in Design.★ 4.5k GitHub starsSkillPatterns, cost review and ready templates for Claude ModsModsmithDannyMac180/skills · by DannyMac180Patterns, cost review and ready templates for Claude Mods (Claude Code plugins whose behaviour is a function-hooks module). Adds what the built-in mod authoring does not: proven designs (fork-check-draw, tool + ledger, mode registry, artifact-backed state), prompt-cache and token-cost review, a vetting pass for someone else's mod, and rules for mods that compose. USE WHEN: build a mod, make a claude mod, mod templates, quiz me after each turn, assumptions tool / register_assumption, supervisor that checks the turn, next-steps check, mode selector / mode registry, effort by domain, model router that keeps the cache, prompt cache cost of a mod, what does this mod cost per turn, review or vet someone's mod before installing, mods that work together, Kanban artifact as shared project state. NOT FOR: classic shell-command hooks in settings.json (PreToolUse etc.), a plain skill or slash command, MCP server authoring, or looking up the hooks API itself (use the engine's plugin-authoring guidance and generated types).★ 535 GitHub starsMCPLet your agents read, send, and react to email autonomouslyAtomic mail agenticAtomic-Mail/atomic-mail-agentic · by Atomic-MailLet your agents read, send, and react to email autonomously, without human involvement★ 266 GitHub starsSkillGenerates two genuinely distinct hook variantsA/B Hook Tester — two hooks, one variable, a real answerOotto-AI/claude-content-skills · by Ootto-AIGenerates two genuinely distinct hook variants for the same reel so you can post-test which opening actually wins. Use when the user says "give me two hooks to test", "A/B this hook", "which opening should I use", "hook variants".★ 139 GitHub stars

More from wshobson

SkillMaster C/.NET backend development patterns for buildingwshobson/agents · by wshobsonMaster C#/.NET backend development patterns for building robust APIs, MCP servers, and enterprise applications. Covers async/await, dependency injection, Entity Framework Core, Dapper, configuration, caching, and testing with xUnit. Use when developing .NET backends, reviewing C# code, or designing API architectures.★ 39.9k GitHub starsSkillImplement WCAG 2.2 compliant interfaces with mobileAccessibility compliancewshobson/agents · by wshobsonImplement WCAG 2.2 compliant interfaces with mobile accessibility, inclusive design patterns, and assistive technology support. Use when auditing accessibility, implementing ARIA patterns, building for screen readers, or ensuring inclusive user experiences.★ 39.9k GitHub starsSkillMaster Material Design 3 and Jetpack Compose patternsAndroid Mobile Designwshobson/agents · by wshobsonMaster Material Design 3 and Jetpack Compose patterns for building native Android apps. Use when designing Android interfaces, implementing Compose UI, or following Google's Material Design guidelines.★ 39.9k GitHub starsSkillMigrate from AngularJS to Angular using hybrid modeAngular migrationwshobson/agents · by wshobsonMigrate from AngularJS to Angular using hybrid mode, incremental component rewriting, and dependency injection updates. Use when upgrading AngularJS applications, planning framework migrations, or modernizing legacy Angular code.★ 39.9k GitHub starsSkillUnderstand anti-reversing, obfuscationAnti reversing techniqueswshobson/agents · by wshobsonUnderstand anti-reversing, obfuscation, and protection techniques encountered during software analysis. Use this skill when analyzing malware evasion techniques, when implementing anti-debugging protections for CTF challenges, when reverse engineering packed binaries, or when building security research tools that need to detect virtualized environments.★ 39.9k GitHub starsSkillBuild production Apache Airflow DAGs with best practicesApache Airflow DAG Patternswshobson/agents · by wshobsonBuild production Apache Airflow DAGs with best practices for operators, sensors, testing, and deployment. Use when creating data pipelines, orchestrating workflows, or scheduling batch jobs.★ 39.9k GitHub stars