Use when building React components with Tailwind CSS v4, shadcn/ui, or Radix primitives. Use when writing className strings, cva variants, or arbitrary CSS variable values in Tailwind. Critical for avoiding v3 syntax that silently breaks in v4.
View on GitHubplugins/saurun/skills/react-tailwind-v4-components/SKILL.md
February 5, 2026
Select agents to install to:
npx add-skill https://github.com/fiatkongen/saurun-marketplace/blob/main/plugins/saurun/skills/react-tailwind-v4-components/SKILL.md -a claude-code --skill react-tailwind-v4-componentsInstallation paths:
.claude/skills/react-tailwind-v4-components/# React Components with Tailwind v4 + shadcn/ui
## Overview
Reference for building React components with Tailwind CSS v4, shadcn/ui, and Radix. **Primary purpose:** prevent v3 syntax habits that silently break in v4.
## Tailwind v4 Syntax — Critical Changes
### CSS Variable Syntax: Parentheses, NOT Brackets
```tsx
// v4 CORRECT — parentheses for READING CSS variables
<div className="bg-(--brand-color) text-(--text-color) ring-(--accent)">
// v3 WRONG — square brackets
<div className="bg-[--brand-color] text-[var(--text-color)]">
```
**This is the #1 mistake.** Square bracket CSS variable syntax silently fails in v4.
**This applies EVERYWHERE — including inside cva() strings and arbitrary values.**
### Opacity Modifiers with CSS Variables
Opacity modifiers work with parentheses syntax:
```tsx
<div className="bg-(--brand-color)/10 border-(--accent)/50 text-(--heading)/80">
```
### Setting CSS Variables Per Variant
**`theme()` is deprecated.** Use `var(--color-*)` directly. Tailwind v4 exposes all theme values as CSS variables: `--color-blue-500`, `--spacing-4`, `--radius-lg`, etc.
**Option A: data-attribute + CSS (preferred for many variants):**
```css
/* In your CSS file */
[data-variant="info"] { --alert-accent: var(--color-blue-500); }
[data-variant="success"] { --alert-accent: var(--color-green-500); }
[data-variant="warning"] { --alert-accent: var(--color-amber-500); }
```
```tsx
// Component uses the CSS variable, variant sets it via data attribute
const alertVariants = cva("border-(--alert-accent) bg-(--alert-accent)/10", {
variants: {
variant: {
info: "text-blue-900",
success: "text-green-900",
warning: "text-amber-900",
},
},
})
export function Alert({ variant, className, ...props }: AlertProps) {
return <div data-variant={variant} className={cn(alertVariants({ variant }), className)} {...props} />
}
```
**Option B: inline style (acceptable for dynamic CSS custom properties):**
```tsx
// When you need to SET