Tailwind Plugins
Build custom Tailwind CSS plugins that add utilities, components, and variants. Configure theme extensions, create design-system primitives, and author shareable plugins with proper type safety and documentation.
You are an expert in the Tailwind CSS plugin API (v3.4+ and v4). You create custom utilities, component classes, and variants that integrate seamlessly with Tailwind's JIT engine, respect the theme configuration, and compose naturally with existing utility classes.
## Key Points
- **Using `addUtilities` when values should be dynamic** -- prefer `matchUtilities` so users can pass arbitrary values with bracket syntax like `text-shadow-[0_2px_4px_red]`.
- **Registering dozens of static component classes** -- this recreates Bootstrap; keep plugins utility-first and compose in markup.
- **Ignoring `important` config** -- always let Tailwind handle specificity; avoid `!important` in plugin CSS.
- **Not declaring `content` paths for plugin-added classes** -- classes generated by `addComponents` still need to appear in scanned files.
- Adding design-system tokens (spacing scales, type scales, color aliases) as first-class Tailwind values.
- Creating project-specific utilities like fluid type, logical properties, or glass effects.
- Wrapping third-party CSS patterns (e.g., skeleton loaders, focus rings) as composable Tailwind classes.
- Building a shareable Tailwind preset for a multi-app monorepo.
- Implementing custom variants for states Tailwind doesn't cover (e.g., `hocus`, `aria-current`).
## Quick Example
```bash
npm install tailwindcss@latest
npm install -D postcss autoprefixer
```
```typescript
// Ignores user theme customization
plugin(function ({ addUtilities }) {
addUtilities({ ".text-shadow-sm": { textShadow: "0 1px 2px rgb(0 0 0 / 0.1)" } });
});
```skilldb get design-tool-services-skills/tailwind-pluginsFull skill: 196 linesTailwind CSS Custom Plugins
You are an expert in the Tailwind CSS plugin API (v3.4+ and v4). You create custom utilities, component classes, and variants that integrate seamlessly with Tailwind's JIT engine, respect the theme configuration, and compose naturally with existing utility classes.
Core Philosophy
Extend, Don't Override
Plugins should add capabilities to Tailwind's existing system. Use theme.extend to add values without clobbering defaults. Register utilities under clear namespaces so they coexist with core utilities.
Theme-Aware by Default
Every magic number in a plugin should reference theme() values. This ensures dark mode, responsive breakpoints, and custom theme overrides propagate automatically.
Composable Primitives
Design plugin utilities as single-purpose building blocks. A .card component class is less flexible than composable .surface, .rounded-card, and .shadow-card utilities.
Setup
npm install tailwindcss@latest
npm install -D postcss autoprefixer
// tailwind.config.ts
import type { Config } from "tailwindcss";
import plugin from "tailwindcss/plugin";
export default {
content: ["./src/**/*.{ts,tsx,html}"],
theme: {
extend: {
colors: {
brand: { 500: "#6366f1", 600: "#4f46e5" },
},
},
},
plugins: [
// inline plugin or require("./plugins/my-plugin")
],
} satisfies Config;
Key Patterns
Do: Use matchUtilities for value-driven utilities
plugin(function ({ matchUtilities, theme }) {
matchUtilities(
{ "text-shadow": (value) => ({ textShadow: value }) },
{ values: theme("textShadow") }
);
});
Not: Hard-code values inside the plugin
// Ignores user theme customization
plugin(function ({ addUtilities }) {
addUtilities({ ".text-shadow-sm": { textShadow: "0 1px 2px rgb(0 0 0 / 0.1)" } });
});
Do: Register custom variants with addVariant
plugin(function ({ addVariant }) {
addVariant("hocus", ["&:hover", "&:focus"]);
addVariant("group-hocus", [":merge(.group):hover &", ":merge(.group):focus &"]);
});
// Usage: <button class="hocus:ring-2">
Common Patterns
Fluid typography utility
plugin(function ({ matchUtilities, theme }) {
matchUtilities(
{
"text-fluid": (value: string) => {
const [min, max] = value.split("_");
return {
fontSize: `clamp(${min}, 2vw + 1rem, ${max})`,
};
},
},
{
values: {
sm: "0.875rem_1.125rem",
base: "1rem_1.25rem",
lg: "1.25rem_1.75rem",
xl: "1.5rem_2.25rem",
},
}
);
});
// Usage: <h1 class="text-fluid-xl">
Component class with theme values
plugin(function ({ addComponents, theme }) {
addComponents({
".btn": {
padding: `${theme("spacing.2")} ${theme("spacing.4")}`,
borderRadius: theme("borderRadius.lg"),
fontWeight: theme("fontWeight.semibold"),
fontSize: theme("fontSize.sm"),
transition: "background-color 150ms ease",
},
".btn-primary": {
backgroundColor: theme("colors.brand.500"),
color: theme("colors.white"),
"&:hover": { backgroundColor: theme("colors.brand.600") },
},
});
});
Logical property utilities
plugin(function ({ matchUtilities, theme }) {
matchUtilities(
{
"mbs": (value) => ({ marginBlockStart: value }),
"mbe": (value) => ({ marginBlockEnd: value }),
"mis": (value) => ({ marginInlineStart: value }),
"mie": (value) => ({ marginInlineEnd: value }),
},
{ values: theme("margin"), supportsNegativeValues: true }
);
});
// Usage: <div class="mbs-4 mie-2">
Shareable plugin with options
// plugins/glass.ts
import plugin from "tailwindcss/plugin";
export const glass = plugin.withOptions<{ blur?: string }>(
(options = {}) =>
function ({ addUtilities }) {
const blur = options.blur ?? "12px";
addUtilities({
".glass": {
background: "rgba(255, 255, 255, 0.1)",
backdropFilter: `blur(${blur})`,
border: "1px solid rgba(255, 255, 255, 0.15)",
},
});
},
() => ({}) // optional theme extensions
);
// tailwind.config.ts
// plugins: [glass({ blur: "16px" })]
Dark mode aware base styles
plugin(function ({ addBase, theme }) {
addBase({
":root": {
"--surface": theme("colors.white"),
"--on-surface": theme("colors.gray.900"),
},
".dark": {
"--surface": theme("colors.gray.900"),
"--on-surface": theme("colors.gray.100"),
},
});
});
Anti-Patterns
- Using
addUtilitieswhen values should be dynamic -- prefermatchUtilitiesso users can pass arbitrary values with bracket syntax liketext-shadow-[0_2px_4px_red]. - Registering dozens of static component classes -- this recreates Bootstrap; keep plugins utility-first and compose in markup.
- Ignoring
importantconfig -- always let Tailwind handle specificity; avoid!importantin plugin CSS. - Not declaring
contentpaths for plugin-added classes -- classes generated byaddComponentsstill need to appear in scanned files.
When to Use
- Adding design-system tokens (spacing scales, type scales, color aliases) as first-class Tailwind values.
- Creating project-specific utilities like fluid type, logical properties, or glass effects.
- Wrapping third-party CSS patterns (e.g., skeleton loaders, focus rings) as composable Tailwind classes.
- Building a shareable Tailwind preset for a multi-app monorepo.
- Implementing custom variants for states Tailwind doesn't cover (e.g.,
hocus,aria-current).
Install this skill directly: skilldb add design-tool-services-skills
Related Skills
Canvas API
Draw graphics and generate images with the HTML Canvas 2D API and node-canvas. Render charts, create dynamic OG images, manipulate pixels, and build server-side image generation pipelines with the Canvas rendering context.
Chromatic
Automate visual regression testing with Chromatic. Configure snapshot capture, UI review workflows, and TurboSnap to catch unintended visual changes in Storybook components before they reach production.
Design Tokens
Manage cross-platform design tokens with Style Dictionary. Define token schemas, configure transforms and formats, and output CSS custom properties, Tailwind themes, iOS, and Android values from a single source of truth.
Figma API
Integrate with the Figma REST API and webhooks to read design files, extract components, manage variables, export images, and sync comments. Covers authentication, pagination, and real-time event handling for design-to-code workflows.
Iconify
Integrate icons at scale with the Iconify framework. Use framework-specific components for React and Vue, register custom icon sets, and leverage the Iconify API for on-demand SVG delivery without bundling thousands of icons.
Sharp
Process images at high performance with Sharp. Resize, crop, convert formats, extract metadata, and build streaming pipelines for thumbnails, responsive images, and batch transformations using libvips under the hood.