https://github.com/agolosnichenko/eslint-plugin-tailwind-grouping
ESLint plugin to group and organize Tailwind CSS classes
https://github.com/agolosnichenko/eslint-plugin-tailwind-grouping
code-style eslint eslint-plugin formatting tailwind tailwindcss
Last synced: 16 days ago
JSON representation
ESLint plugin to group and organize Tailwind CSS classes
- Host: GitHub
- URL: https://github.com/agolosnichenko/eslint-plugin-tailwind-grouping
- Owner: agolosnichenko
- License: mit
- Created: 2025-11-14T06:00:30.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2025-11-14T17:49:17.000Z (7 months ago)
- Last Synced: 2025-11-30T14:09:37.317Z (6 months ago)
- Topics: code-style, eslint, eslint-plugin, formatting, tailwind, tailwindcss
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/eslint-plugin-tailwind-grouping
- Size: 49.8 KB
- Stars: 5
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# ESLint Plugin: Tailwind Grouping
An ESLint plugin that automatically groups and organizes Tailwind CSS classes into semantic categories, improving
readability and maintainability of your React/JSX code.
## 📋 Table of Contents
- [Problem](#problem)
- [Solution](#solution)
- [Installation](#installation)
- [Usage](#usage)
- [Configuration](#configuration)
- [Examples](#examples)
- [Development](#development)
## Problem
Large Tailwind className strings are difficult to read and maintain:
```jsx
```
## Solution
The plugin automatically transforms long className strings into organized, commented groups using `clsx`:
```jsx
```
## Installation
```bash
npm install --save-dev eslint-plugin-tailwind-grouping
# or
yarn add -D eslint-plugin-tailwind-grouping
# or
pnpm add -D eslint-plugin-tailwind-grouping
```
## Usage
### ESLint Configuration (Flat Config - ESLint 9+)
```javascript
// eslint.config.js
import tailwindGrouping from 'eslint-plugin-tailwind-grouping';
export default [
{
plugins: {
'tailwind-grouping': tailwindGrouping
},
rules: {
'tailwind-grouping/group-classes': ['warn', {
threshold: 5,
include: ['**/*.tsx', '**/*.jsx'],
exclude: ['**/*.test.tsx']
}]
}
}
];
```
### ESLint Configuration (Legacy)
```json
{
"plugins": [
"tailwind-grouping"
],
"rules": {
"tailwind-grouping/group-classes": [
"warn",
{
"threshold": 5
}
]
}
}
```
### Using with Prettier
This plugin is compatible with Prettier. Make sure to run ESLint with `--fix` flag:
```bash
eslint --fix .
```
## Configuration
### Options
```typescript
{
// Minimum number of classes required to trigger transformation
// Default: 0
threshold?: number;
// Glob patterns for files to include
// Default: [] (all files)
include?: string[];
// Glob patterns for files to exclude
// Default: [] (no exclusions)
exclude?: string[];
// Custom mapping of groups to class patterns
// Default: DEFAULT_GROUP_MAPPING
mapping?: {
[groupName: string]: string[];
};
// Custom order of groups
// Default: ['Size', 'Layout', 'Spacing', 'Border', 'Background', 'Text', 'Effects', 'Others']
groupOrder?: string[];
// Name of the utility function to use
// Default: 'clsx'
utilityFunction?: string;
// Whether to include group name comments in the output
// Default: true
showGroupNames?: boolean;
// Comment template for group names
// Can be a preset name or a custom template string with variables
// Default: "// {groupName}"
// Presets: 'line', 'block', 'jsdoc', 'bracket', 'numbered', 'verbose'
// Variables: {groupName}, {index}, {count}
commentTemplate?: string;
// Sorting order for classes within each group
// Default: "no-sort"
// Options: 'no-sort' | 'asc' | 'desc' | 'official'
order?: 'no-sort' | 'asc' | 'desc' | 'official';
}
```
### Example: Custom Mapping
```javascript
{
"tailwind-grouping/group-classes":
["warn", {
"threshold": 3,
"mapping": {
"Size": ["w-*", "h-*", "min-w-*", "max-w-*"],
"Colors": ["bg-*", "text-*", "border-*"],
"Spacing": ["p-*", "m-*", "gap-*"],
"Others": []
},
"groupOrder": ["Size", "Colors", "Spacing", "Others"]
}]
}
```
### Example: Custom Utility Function
```javascript
{
"tailwind-grouping/group-classes":
["warn", {
"utilityFunction": "cn" // Use shadcn/ui's cn function
}]
}
```
### Example: Without Group Name Comments
If you prefer cleaner output without the group name comments, you can disable them:
```javascript
{
"tailwind-grouping/group-classes":
["warn", {
"showGroupNames": false
}]
}
```
**Output with `showGroupNames: false`:**
```jsx
Content
```
**Output with `showGroupNames: true` (default):**
```jsx
Content
```
### Example: Custom Comment Templates
Customize how group comments appear using templates with variables or presets:
#### Using Preset Templates
```javascript
{
"tailwind-grouping/group-classes": ["warn", {
"commentTemplate": "block" // Use block comment style
}]
}
```
**Available Presets:**
- `line`: `// {groupName}` (default)
- `block`: `/* {groupName} */`
- `jsdoc`: `/** {groupName} **/`
- `bracket`: `// [{groupName}]`
- `numbered`: `// {index}. {groupName}`
- `verbose`: `// {groupName} ({count} classes)`
#### Using Custom Templates
Create your own templates with these variables:
- `{groupName}`: Name of the group (e.g., "Size", "Spacing")
- `{index}`: 1-based position of the group
- `{count}`: Number of classes in the group
```javascript
{
"tailwind-grouping/group-classes": ["warn", {
"commentTemplate": "// {index}. {groupName} ({count})"
}]
}
```
**Example outputs:**
```jsx
// With commentTemplate: "/* {groupName} */"
// With commentTemplate: "// {index}. {groupName}"
// With commentTemplate: "// {groupName} ({count})"
// With commentTemplate: "// [{index}] {groupName} - {count} classes"
```
### Example: Class Sorting
You can control how classes are sorted within each group:
```javascript
{
"tailwind-grouping/group-classes": ["warn", {
"order": "asc" // Sort alphabetically A-Z
}]
}
```
**Options:**
- `"no-sort"` (default): Preserve original order
- `"asc"`: Sort alphabetically A-Z
- `"desc"`: Sort alphabetically Z-A
- `"official"`: Use Tailwind's official class ordering (same as prettier-plugin-tailwindcss)
**Example output with `order: "asc"`:**
```jsx
```
**Note:** The plugin automatically removes duplicate classes, keeping only the first occurrence.
## Examples
### Before
```jsx
Content
```
### After (with threshold: 3)
```jsx
Content
```
### Handling Modifiers
The plugin preserves all Tailwind modifiers (responsive, state, dark mode, etc.):
```jsx
// Input
className = "md:flex lg:grid hover:bg-blue-500 dark:bg-gray-900"
// Output
className = {
clsx(
// Layout
"md:flex lg:grid",
// Background
"hover:bg-blue-500 dark:bg-gray-900"
)
}
```
### Handling Arbitrary Values
Arbitrary values are properly grouped:
```jsx
// Input
className = "w-[500px] h-[calc(100vh-80px)] bg-[#ff0000]"
// Output
className = {
clsx(
// Size
"w-[500px] h-[calc(100vh-80px)]",
// Background
"bg-[#ff0000]"
)
}
```
## Development
### Setup
```bash
# Install dependencies
npm install
# Build the plugin
npm run build
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Lint the code
npm run lint
```
### Running Tests
```bash
npm test
```
### Testing Locally
To test the plugin in a project before publishing:
```bash
# In the plugin directory
npm link
# In your project directory
npm link eslint-plugin-tailwind-grouping
```
### Design Principles
- **Immutability**: All domain objects are immutable
- **Single Responsibility**: Each class has one clear purpose
- **Dependency Injection**: Services receive dependencies via constructor
- **Testability**: Pure business logic separated from infrastructure
- **Type Safety**: Full TypeScript coverage with strict mode
## Contributing
Contributions are welcome! Please ensure:
1. All tests pass (`npm test`)
2. Code follows the existing architecture
3. New features include tests
4. TypeScript types are properly defined
## License
MIT
## Links
- [GitHub Repository](https://github.com/agolosnichenko/eslint-plugin-tailwind-grouping)
- [Issue Tracker](https://github.com/agolosnichenko/eslint-plugin-tailwind-grouping/issues)
- [Tailwind CSS Documentation](https://tailwindcss.com)
- [ESLint Documentation](https://eslint.org)