Use when authoring a custom Tailwind CSS plugin to add utilities, components, base styles, or variants, regardless of whether the host project runs Tailwind v3 (JS plugin in tailwind-config-js) or v4 (JS plugin loaded via @plugin or the CSS-native @utility directive). Prevents the four most common plugin-authorship traps: registering utilities through addBase (where variants do not apply), forgetting the second-argument default theme so theme('tabSize') returns undefined, omitting the values map on matchUtilities causing zero classes to compile, and importing tailwindcss/plugin in a v4-only project where the package no longer exists at runtime. Covers the full plugin() signature (addUtilities, addComponents, addBase, addVariant, matchUtilities, matchComponents, matchVariant, theme, config, corePlugins, e), plugin-withOptions for parameterised plugins, shipping default theme values through the configFn, the v4-native @utility name-* with --value() and --modifier(), the v4 @custom-variant directive, the v4 @plu
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
Use when authoring a custom Tailwind CSS plugin to add utilities, components, base styles, or variants, regardless of whether the host project runs Tailwind v3 (JS plugin in tailwind-config-js) or v4 (JS plugin loaded via @plugin or the CSS-native @utility directive). Prevents the four most common plugin-authorship traps: registering utilities through addBase (where variants do not apply), forgetting the second-argument default theme so theme('tabSize') returns undefined, omitting the values map on matchUtilities causing zero classes to compile, and importing tailwindcss/plugin in a v4-only project where the package no longer exists at runtime. Covers the full plugin() signature (addUtilities, addComponents, addBase, addVariant, matchUtilities, matchComponents, matchVariant, theme, config, corePlugins, e), plugin-withOptions for parameterised plugins, shipping default theme values through the configFn, the v4-native @utility name-* with --value() and --modifier(), the v4 @custom-variant directive, the v4 @plugin loader for legacy JS plugins, theme path syntax (theme('colors.red.500'), theme('spacing.4')), variants arrays on addUtilities under v3, and packaging a plugin as a publishable npm module. Keywords: tailwind plugin, custom plugin, plugin function, addUtilities, addComponents, addBase, addVariant, matchUtilities, matchComponents, matchVariant, plugin.withOptions, plugin-withOptions, theme function, config function, corePlugins, e helper, tabSize matchUtilities, hocus variant, peer variant plugin, @utility v4, @utility name-*, --value(), --modifier(), --alpha(), --spacing(), @custom-variant, @plugin tailwind v4, load legacy plugin v4, theme('colors.red.500'), theme('spacing.4'), npm package tailwind plugin, publish tailwind plugin, my plugin classes not working, matchUtilities not generating, how do I add a custom utility, how do I write a tailwind plugin, where do plugin classes go, why doesn't my variant apply, tailwind-config-js plugins array.
license
MIT
compatibility
Designed for Claude Code. Requires Tailwind CSS v3.4 or v4.0+.
metadata
{"author":"OpenAEC-Foundation","version":"1.0"}
Tailwind CSS Custom Plugins
Tailwind exposes three authoring paths for custom styles : the JS
plugin() API (works in v3 and v4 for back-compat), v4's CSS-native
@utility directive, and v4's @custom-variant directive. Pick by
constraint, not by taste.
Companion skills :
tailwind-impl-config-v4 : @utility, @custom-variant, @plugin
directives in depth
ALWAYS use addComponents (not addUtilities) for multi-utility
recipes. Component classes are emitted into the components layer so
user-applied utilities (btn rounded-none) override them.
values is the map of { classSuffix: value }. Reading from
theme('tabSize') automatically picks up user overrides in
tailwind.config.jstheme.extend.tabSize. Without a values map,
matchUtilities generates ZERO classes (silent failure).
Arbitrary-value support is automatic : tab-[7] works without
listing 7 in values.
tab-* automatically supports bare integers (tab-3), arbitrary
values (tab-[7]), and theme keys (tab-2). See
tailwind-syntax-functional-utilities for --modifier(),
--alpha(), --spacing().
The path is resolved relative to the CSS file. The plugin file uses
the standard plugin() signature ; the v4 build loads it through the
same JS bridge that maintains v3 compatibility.
Theme Path Syntax
The theme() helper accepts dot-notation paths into the resolved
theme object :
theme('colors.red.500') // '#ef4444'theme('spacing.4') // '1rem'theme('fontSize.lg') // '1.125rem' or [size, { lineHeight }]theme('screens.md') // '768px'theme('fontFamily.sans') // array of family namestheme('borderRadius.full') // '9999px'
Paths trace theme after merging user theme.extend. Missing paths
return undefined, NOT an error : guard with ?? fallback.
Use peerDependencies for tailwindcss, NOT dependencies. A direct
dependency would install a duplicate Tailwind in user node_modules and
break version resolution.
Verification Checklist
Plugin classes appear in compiled CSS. Grep .next/static/css or
the Vite-emitted CSS file for one of your selectors.
Variants apply : hover:my-utility produces a :hover rule, not a
raw rule. If not, you probably registered through addBase.
matchUtilities generates classes for every key in values. Count
selectors in the output bundle.
Arbitrary values work : my-util-[42] produces a CSS rule.
Theme lookups resolve : log theme('colors.brand') from inside the
plugin body during development.
v4 @plugin loading : the plugin file path resolves relative to
the CSS file, NOT the project root.
References
references/methods.md : every helper signature, options, v3-only
vs v3+v4 vs v4-only authoring matrix
references/examples.md : ten full plugin source files with
matching consumer-side usage
references/anti-patterns.md : eight authorship traps with cause,
symptom, fix