Skip to content

Tailwind CSS - Plugins

Tailwind CSS plugins are JavaScript functions that allow you to extend Tailwind’s functionality. They are the key to creating reusable components, adding new utility variants, or integrating complex styling patterns into your project, keeping your tailwind.config.js clean and your design system scalable.

  • Reusability: Package a set of custom styles and logic to be easily shared across multiple projects.
  • Abstraction: Encapsulate complex CSS-in-JS logic into simple utility or component classes.
  • Configuration: Create configurable plugins using plugin.withOptions to allow users to customize class names, theme values, and more.
  • Community: Leverage a rich ecosystem of third-party plugins or contribute your own.

The Tailwind CSS team maintains several official plugins for common features. To use them, you first need to install them via npm and then add them to the plugins array in your tailwind.config.js file.

tailwind.config.js
# Install the official forms and typography plugins
npm install -D @tailwindcss/forms @tailwindcss/typography
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{html,js}'],
theme: {
extend: {},
},
plugins: [
require('@tailwindcss/typography'),
require('@tailwindcss/forms'),
require('@tailwindcss/aspect-ratio'),
require('@tailwindcss/container-queries'),
],
}
  • @tailwindcss/typography: Adds a prose class for beautifully styled long-form text content, like blog posts or documentation pages.
  • @tailwindcss/forms: Provides a basic reset for form elements, making them much easier to style with utility classes.
  • @tailwindcss/aspect-ratio: Adds aspect-w-* and aspect-h-* utilities (now integrated into core as aspect-*, but the plugin provides legacy support).
  • @tailwindcss/container-queries: A polyfill for CSS Container Queries, letting you style elements based on their container’s size using @ variants (e.g., @lg:text-lg).

Creating a plugin involves calling the plugin() function, which receives an object of helper functions to hook into Tailwind’s engine. You can use these helpers to add new base styles, utilities, components, or variants.

tailwind.config.js
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addUtilities, addComponents, theme, e }) {
// Your plugin logic goes here
const customUtilities = {
'.rotate-y-180': {
transform: 'rotateY(180deg)',
},
}
addUtilities(customUtilities)
}),
],
}

Use addUtilities to register new, static CSS utilities. These utilities can be combined with variants like hover: and focus: automatically.

Adding Dynamic Utilities with matchUtilities

Section titled “Adding Dynamic Utilities with matchUtilities”

Use matchUtilities to create utilities that accept a value from your theme or an arbitrary value. For example, creating a text-shadow utility that uses your theme('colors').

// plugin code
matchUtilities(
{
'text-shadow': (value) => ({
textShadow: `1px 1px 2px ${value}`,
}),
},
{ values: theme('colors') }
)
// HTML usage
// <p class="text-shadow-red-500">...</p>
// <p class="text-shadow-[#ABCDEF]">...</p>

Use addComponents to register higher-level component classes, like buttons or cards. These are great for abstracting away common patterns of utilities.

// plugin code
const buttonStyles = {
'.btn': {
padding: `${theme('spacing.2')} ${theme('spacing.4')}`,
borderRadius: theme('borderRadius.md'),
fontWeight: theme('fontWeight.semibold'),
transition: 'all .2s ease',
},
'.btn-primary': {
backgroundColor: theme('colors.blue.500'),
color: theme('colors.white'),
'&:hover': {
backgroundColor: theme('colors.blue.600'),
}
}
}
addComponents(buttonStyles)
// HTML usage
// <button class="btn btn-primary">Click Me</button>

Use addVariant to register your own custom modifiers, like hocus for hover and focus, or a variant for a specific data attribute.

// plugin code
addVariant('hocus', ['&:hover', '&:focus'])
addVariant('group-open', ':merge(.group).open &')
// HTML usage
// <button class="bg-blue-500 hocus:bg-blue-600">...</button>
// <div class="group">
// <span class="group-open:block">...</span>
// </div>

The plugin.withOptions API allows you to create plugins that users can configure. This is the professional way to build a distributable plugin.

./plugins/custom-button.js
const plugin = require('tailwindcss/plugin')
module.exports = plugin.withOptions(function (options = {}) {
// The main plugin function, which has access to the user's options
return function ({ addComponents }) {
const buttonClass = options.buttonClass ?? '.btn-custom'
addComponents({
[buttonClass]: {
backgroundColor: 'purple',
color: 'white',
// ...
}
})
}
})
// tailwind.config.js
module.exports = {
plugins: [
require('./plugins/custom-button.js')({ buttonClass: '.my-super-button' })
],
}