ESLint Plugin
The @styled-cva/eslint-plugin package provides an ESLint rule that suggests extracting JSX elements with many Tailwind classes into named styled components. The rule is fixable, so you can apply the suggestion automatically.
Part of the styled-cva monorepo. Published to npm as @styled-cva/eslint-plugin. Install with your package manager or link the workspace during development.
Rule: prefer-styled-cva
The rule reports when a native HTML element (e.g. button, div, span) has a className with more than a configured number of classes, and suggests extracting it to a styled component. Only lowercase element names are checked (custom components are ignored).
- Default threshold: 5 classes (configurable)
- Fixable: yes — ESLint can add the import, create the styled component, and replace the inline element
Example
Before (reported when class count exceeds the threshold):
<button className="rounded bg-blue-500 px-4 py-2 text-white font-bold hover:bg-blue-600">
Submit
</button>After (auto-fix):
import tw from "@styled-cva/react";
const StyledButton = tw.button`rounded bg-blue-500 px-4 py-2 text-white font-bold hover:bg-blue-600`;
// ...
<StyledButton>Submit</StyledButton>;The plugin recognizes both styled-cva and @styled-cva/react as the styled import.
Run the ESLint fix (e.g. eslint --fix or your editor’s “Fix all”) to apply the extraction automatically.
Installation
In a project that uses @styled-cva/react:
npm install -D @styled-cva/eslint-plugin
# or
bun add -d @styled-cva/eslint-pluginWhen developing in the monorepo, from the repo root:
bun install
bun run --filter @styled-cva/eslint-plugin buildPeer dependencies: eslint (^9), typescript (^5).
Configuration
Use ESLint flat config (e.g. eslint.config.js). Import the plugin and enable the rule:
import styledCvaPlugin from "@styled-cva/eslint-plugin";
export default [
{
plugins: {
"@styled-cva": styledCvaPlugin,
},
rules: {
"@styled-cva/prefer-styled-cva": ["warn", { threshold: 5 }],
},
},
];Options
| Option | Type | Default | Description |
|---|---|---|---|
threshold | number | 5 | Minimum number of classes before the rule is reported. |
Example: only suggest extraction when there are more than 8 classes:
"@styled-cva/prefer-styled-cva": ["warn", { threshold: 8 }]When to use it
- Keep components readable by moving long
classNamestrings into named styled components. - Encourage consistent use of
@styled-cva/react(or styled-cva) in the codebase. - Reduce duplication when the same set of classes is used in multiple places (extract once, reuse the component).