css-to-tailwind-react
v0.4.2
Published
Convert traditional CSS (inline, internal, and external) into Tailwind CSS utility classes for React-based frameworks
Downloads
1,077
Maintainers
Readme
CSS to Tailwind React
Convert traditional CSS (inline, internal, and external) into Tailwind CSS utility classes for React-based frameworks.
Features
✨ Multi-source CSS support: Handles inline styles, internal <style> blocks, and external CSS files
🎯 AST-based parsing: Uses Babel for JSX/TSX and PostCSS for CSS - no regex hacks
🔄 Smart merging: Safely merges Tailwind classes with existing className attributes
⚠️ Safety first: Creates backups before modifications, supports dry-run mode
🎨 Tailwind config aware: Reads your tailwind.config.js for custom scales
📊 Detailed reporting: Shows exactly what changed and what was skipped
Installation
npm install -g css-to-tailwind-reactOr use directly with npx:
npx css-to-tailwind-react ./srcUsage
Basic Usage
npx css-to-tailwind-react ./srcCLI Options
npx css-to-tailwind-react <directory> [options]
Options:
--dry-run Show changes without modifying files
--verbose Show detailed output
--delete-css Delete CSS files when all rules are converted
--skip-external Skip external CSS files (imports)
--skip-inline Skip inline styles
--skip-internal Skip internal <style> blocksExamples
Preview changes (dry-run):
npx css-to-tailwind-react ./src --dry-run --verboseOnly inline styles:
npx css-to-tailwind-react ./src --skip-external --skip-internalFull conversion with CSS cleanup:
npx css-to-tailwind-react ./src --delete-cssSupported Conversions
Inline Styles
Input:
<div style={{ display: "flex", justifyContent: "center", padding: "16px" }}>
Content
</div>Output:
<div className="flex justify-center p-4">
Content
</div>External CSS
Input (styles.css):
.main-head {
font-weight: bold;
text-align: center;
margin-bottom: 20px;
}Component:
import "./styles.css";
function Header() {
return <h1 className="main-head">Title</h1>;
}Output:
import "./styles.css";
function Header() {
return <h1 className="font-bold text-center mb-5">Title</h1>;
}ClassName Merging
Input:
<div className="container" style={{ display: "flex" }}>
Content
</div>Output:
<div className="container flex">
Content
</div>Supported CSS Properties
The following properties are supported in v1:
- Display:
display: flex,display: block, etc. - Position:
position: relative,absolute, etc. - Spacing:
margin,padding(with px to Tailwind scale conversion) - Typography:
font-weight,font-size,text-align - Flexbox:
flex-direction,flex-wrap,justify-content,align-items - Gap:
gap(with spacing scale) - Dimensions:
width,height(basic values and percentages) - Colors:
background-color,color(named, hex, rgb) - Border:
border-radius
What Gets Skipped
The following are intentionally skipped with warnings:
- Pseudo-selectors (
:hover,:focus, etc.) - Media queries
- Nested selectors
- CSS animations and keyframes
- CSS variables (
--*) calc()expressions- Dynamic styles (conditional expressions)
- Complex className expressions
Safety Features
Backups
All original files are backed up to .css-to-tailwind-backups/ before modification. To restore:
# Manual restore
cp -r .css-to-tailwind-backups/* ./Dry Run
Always preview changes first:
npx css-to-tailwind-react ./src --dry-run --verboseDynamic Content Detection
The tool safely skips dynamic expressions:
// These are skipped with warnings
<div style={dynamicStyle} />
<div className={condition ? "a" : "b"} style={{ display: "flex" }} />Configuration
The tool automatically detects and uses your tailwind.config.js if present. It supports:
- Custom spacing scales
- Extended colors
- Custom font sizes
- Border radius values
Example config support:
// tailwind.config.js
module.exports = {
theme: {
extend: {
spacing: {
'18': '4.5rem',
'88': '22rem',
}
}
}
}Programmatic API
import { scanProject, transformFiles } from 'css-to-tailwind-react';
const files = await scanProject('./src');
const results = await transformFiles(files, {
dryRun: false,
deleteCss: true,
skipExternal: false,
skipInline: false,
skipInternal: false,
tailwindConfig: null,
projectRoot: './src'
});
console.log(`Modified ${results.filesModified} files`);Architecture
src/
├── cli.ts # Commander CLI entry
├── scanner.ts # File detection with fast-glob
├── jsxParser.ts # Babel AST transformations
├── cssParser.ts # PostCSS CSS parsing
├── tailwindMapper.ts # CSS to Tailwind conversion engine
├── transformer.ts # Main transformation coordinator
├── fileWriter.ts # Safe file operations with backups
└── utils/
├── logger.ts # Structured logging
└── config.ts # Tailwind config loadingLimitations
v1 Limitations
- No pseudo-selectors:
:hover,:focus, etc. are skipped - No media queries: Responsive styles are not converted
- No SCSS/Sass: Plain CSS only
- Limited value formats: Pixel values and standard units work best
- No complex selectors: Only simple class selectors (
.classname) - No CSS-in-JS: Styled-components, emotion, etc. not supported
Best Practices
- Commit your code before running
- Use
--dry-runfirst to preview changes - Review warnings - some styles may need manual conversion
- Test thoroughly after conversion
- Keep backups until you're confident
Troubleshooting
"No supported files found"
Ensure your target directory contains .js, .jsx, .ts, .tsx, or .css files. The tool automatically ignores node_modules, .next, dist, and build directories.
"Failed to parse"
Some JavaScript/TypeScript syntax may not be supported. Ensure your code is valid and doesn't use experimental features.
Missing Tailwind classes
The tool uses a default Tailwind config if none is found. Create a tailwind.config.js for custom scales.
Too many warnings
Use --verbose to see detailed output about what's being skipped and why.
Contributing
Contributions welcome! Please ensure:
- Code follows TypeScript strict mode
- All tests pass
- New features include tests
- Documentation is updated
License
MIT
Changelog
1.0.0
- Initial release
- Inline style conversion
- External CSS support
- Internal style support
- Backup and dry-run modes
- Tailwind config detection
