A Claude Code skill that enforces Radix Themes components over raw HTML and Tailwind CSS in React/Next.js projects.
This skill automatically triggers when writing React/Next.js UI code and enforces consistent, theme-driven component usage:
| Prevents | Enforces |
|---|---|
| Inline Tailwind classes | Theme props (gap="3", size="2") |
className for styling |
Component variants and props |
Raw HTML (<div>, <button>, <p>) |
Radix components (<Flex>, <Button>, <Text>) |
| Simple 3rd party UI libs | Radix equivalents |
git clone https://github.com/ag0x00/enforce-radix-themes ~/.claude/skills/enforce-radix-themesDownload enforce-radix-themes.skill from releases and install via Claude Code.
// BAD - Tailwind classes, raw HTML
<div className="flex flex-col gap-4 p-6">
<h1 className="text-2xl font-bold">Settings</h1>
<button className="bg-blue-600 text-white px-4 py-2">Save</button>
</div>
// GOOD - Radix Themes components
import { Flex, Heading, Button } from '@radix-ui/themes';
<Flex direction="column" gap="4" p="6">
<Heading size="6">Settings</Heading>
<Button>Save</Button>
</Flex><Flex direction={{ initial: "column", md: "row" }}>
<Grid columns={{ initial: "1", md: "2", lg: "3" }}>
<Text size={{ initial: "2", md: "3" }}>// Motion wrappers allowed with style prop (not className)
<motion.div style={{ width: '100%' }} animate={{ opacity: 1 }}>
<Flex gap="3">{/* Radix components inside */}</Flex>
</motion.div>Both systems can coexist temporarily during migration - new code must use Radix Themes.
| Instead of | Use |
|---|---|
<div className="flex"> |
<Flex> |
<div> |
<Box> |
<div className="grid"> |
<Grid> |
<main> |
<Container> |
<section> |
<Section> |
| Instead of | Use |
|---|---|
<h1>-<h6> |
<Heading> |
<p>, <span> |
<Text> |
<a> |
<Link> |
| Instead of | Use |
|---|---|
<button> |
<Button> |
<input> |
<TextField.Root> |
<textarea> |
<TextArea> |
<select> |
<Select.Root> |
<input type="checkbox"> |
<Checkbox> |
| Tailwind | Radix Prop |
|---|---|
gap-4 |
gap="4" |
p-4, px-4 |
p="4", px="4" |
text-sm |
size="2" |
font-bold |
weight="bold" |
text-gray-500 |
color="gray" |
The skill handles 3rd party components intelligently:
If a direct Radix equivalent exists, replace it:
| 3rd Party | Radix Replacement |
|---|---|
react-spinners |
<Spinner /> |
react-loading-skeleton |
<Skeleton> |
| Simple tooltip libs | <Tooltip> |
| Simple modal libs | <Dialog.Root> |
| Simple dropdown libs | <DropdownMenu.Root> |
react-toggle |
<Switch /> |
react-avatar |
<Avatar> |
For complex components without direct equivalents:
// FLAG: ThirdPartyDatePicker - no Radix equivalent
// OPTION: Build custom using Popover + Calendar primitives
<Box mb="4">
<ThirdPartyDatePicker />
</Box>
// FLAG: TipTap - complex internals, keep dependency
<RichTextEditor />Install and configure Radix Themes in your project:
npm install @radix-ui/themes// app/layout.tsx
import '@radix-ui/themes/styles.css';
import { Theme } from '@radix-ui/themes';
export default function RootLayout({ children }) {
return (
<html>
<body>
<Theme accentColor="cyan" grayColor="slate" radius="medium">
{children}
</Theme>
</body>
</html>
);
}enforce-radix-themes/
├── skill.md # Main skill instructions
├── enforce-radix-themes.skill # Portable skill file
├── references/
│ └── radix-themes-api.md # Offline API reference
└── LICENSE.txt
MIT