8000 GitHub - christophe77/tailwind-dx: Write readable, maintainable Tailwind classNames by organizing them by intent
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

christophe77/tailwind-dx

Repository files navigation

πŸŒ€ tailwind-dx

npm build coverage license bundle size

Better classNames. Less eye-bleed. DX that actually feels good.

tailwind-dx is a tiny utility that helps you write readable, maintainable Tailwind classNames by organizing them by intent β€” like layout, spacing, typography, and more.

No more 200-character className strings that look like a CSS ransom note.


πŸš€ Why tho?

Tailwind is awesome. But reading your class strings after 3 espressos and 5 months of tech debt?

'flex items-center justify-between px-4 py-2 text-gray-800 shadow rounded-md';

Now compare:

twDX({
	layout: 'flex items-center justify-between',
	spacing: 'px-4 py-2',
	typography: 'text-gray-800',
	effects: 'shadow',
	borders: 'rounded-md',
});

Boom. Readable. Maintainable. Your eyes and your team will thank you.


✨ Features

  • 🧠 Group Tailwind classes by purpose (layout, spacing, typography, etc.)
  • 🧱 Support for reusable class presets (like card, buttonPrimary, etc.)
  • 🧼 Cleaner className logic in React, Preact, Solid, whatever.
  • 🦾 Written in TypeScript. Minimal. Zero deps.
  • 🎯 ESLint validation for proper class categorization
  • 🌈 Support for responsive, state, and dark mode variants
  • πŸ€– LLM-friendly structure for better AI assistance

πŸ€– LLM & IDE Friendly

tailwind-dx is designed to be extremely friendly for both LLM coding agents and IDE autocompletion:

  1. Structured Input: The layer-based organization makes it easy for LLMs to understand and generate code
  2. ESLint Validation: Automatic validation of class placement in correct layers
  3. Predictable Patterns: Consistent structure makes it easier for AI to generate correct code
  4. Self-Documenting: The layer names serve as natural documentation
  5. IDE Support: Get autocompletion for:
    • Layer names (layout, spacing, typography, etc.)
    • Class names within each layer
    • Variants (responsive, state, dark mode)

Example of LLM-friendly code generation:

// Easy for LLMs to understand and generate
twDX({
	layout: 'flex items-center justify-between',
	spacing: 'px-4 py-2',
	typography: 'text-gray-800 dark:text-white',
	effects: 'shadow hover:shadow-lg',
	borders: 'rounded-md focus:ring-2',
});

πŸ“¦ Installation

npm install tailwind-dx

or

yarn add tailwind-dx

πŸ› οΈ Usage

Basic usage

import { twDX } from 'tailwind-dx';

const className = twDX({
	layout: 'flex items-center justify-between',
	spacing: 'px-4 py-2',
	typography: 'text-gray-800',
	borders: 'rounded-md',
	effects: 'shadow-md',
});

ESLint Integration

To enforce proper class placement in your project, add the ESLint plugin:

  1. Install the plugin:
npm install -D tailwind-dx
  1. Add to your ESLint config:

For traditional config (.eslintrc.js):

module.exports = {
	plugins: ['tailwind-dx'],
	extends: ['plugin:tailwind-dx/recommended'],
	// ... your other config
};

For flat config (eslint.config.js):

import tailwindDxPlugin from 'tailwind-dx/eslint-rules';

export default [
	{
		plugins: {
			'tailwind-dx': tailwindDxPlugin,
		},
		rules: {
			'tailwind-dx/layers': 'error',
		},
	},
];

Now ESLint will validate that your classes are in the correct layers:

// ❌ This will show an error
twDX({
	layout: 'text-lg', // Error: Class "text-lg" should be in the "typography" layer
	typography: 'flex', // Error: Class "flex" should be in the "layout" layer
});

// βœ… This is correct
twDX({
	layout: 'flex',
	typography: 'text-lg',
});

Use with variants

twDX({
	// Responsive variants
	layout: 'flex md:flex-col lg:flex-row',

	// Dark mode variant
	typography: 'text-gray-800 dark:text-white',

	// State variants
	effects: 'shadow hover:shadow-lg',
	borders: 'rounded-md focus:ring-2',
});

Use with presets

twDX({ preset: 'card' });

You can define your own presets in src/index.ts or extend it in your own wrapper.

const presets = {
	card: 'bg-white rounded-lg shadow-md p-4',
	buttonPrimary: 'bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700',
	centerFlex: 'flex justify-center items-center',
};

πŸ§ͺ Real-world example

export function Card() {
	return (
		<div
			className={twDX({
				layout: 'flex flex-col gap-4',
				typography: 'text-gray-800 dark:text-white',
				spacing: 'p-6',
				borders: 'rounded-xl',
				effects: 'shadow-lg hover:shadow-xl',
			})}
		>
			<h2 className={twDX({ typography: 'text-xl font-bold' })}>
				Hello, TailwindDX
			</h2>
			<p
				className={twDX({
					typography: 'text-sm text-gray-500 dark:text-gray-400',
				})}
			>
				Clean classNames, clean mind.
			</p>
		</div>
	);
}

βš™οΈ Pro Tips

Want conditional classes? Use with clsx or classnames:

import { clsx } from 'clsx';

const className = clsx(
	twDX({ preset: 'card' }),
	isActive && 'ring-2 ring-blue-500',
);

πŸ§™ Roadmap (aka Things I Might Do While Procrastinating)

  • 🧩 Plugin system for presets
  • 🧠 VSCode IntelliSense extension
  • 🧼 Linter plugin to auto-split long classNames into twDX
  • πŸͺ„ Babel/TS transform that turns twDX into strings at build time

πŸ§‘β€πŸ’» Contributing

Got ideas? Found bugs? Want to add a tailwind-dx theme song? Open a PR or issue. We're just getting started.


πŸͺͺ License

MIT β€” use it, abuse it, remix it.


✨ Final thought

Writing Tailwind should feel like composing UI, not like decoding The Matrix.
Let tailwind-dx clean up your className soup. 🍜


About

Write readable, maintainable Tailwind classNames by organizing them by intent

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published
0