A next-generation, Tailwind-like JIT CSS/PostCSS plugin with a powerful plugin system, support for arbitrary values, variants (including dark mode and RTL), efficient watch mode, and CSS variable theme support.
RelaxCSS can be used as a PostCSS plugin (recommended for most build pipelines) or as a standalone CLI tool.
RelaxCSS is a drop-in PostCSS plugin. It works with PostCSS v8+ and integrates with any PostCSS-based build system (Webpack, Vite, Parcel, etc).
// postcss.config.js
const relaxcss = require('relaxcss');
module.exports = {
plugins: [
require('postcss-import'), // must be first
relaxcss({
// custom config here
}),
require('autoprefixer'),
// ...
]
};
- Supports all RelaxCSS features: JIT utilities, plugins, variants, dark mode, RTL, CSS variables, and more.
- Use your
relaxcss.config.js
for custom configuration. - Compatible with PostCSS v8+ and all major build tools.
- PostCSS Plugin Usage
- Table of Contents
- Features
- Installation
- Quick Start
- Usage as CLI
- Usage as PostCSS Plugin
- Configuration
- Arbitrary Values
- Variants & Responsive Utilities
- CSS Variable Theme Support
- @apply and Utility Extraction
- Production Usage & PurgeCSS
- Advanced Examples
- FAQ
- License
- JIT utility generation (like Tailwind, but faster)
- Plugin system for user utilities
- Arbitrary value support (e.g.
bg-[#222]
,p-[4px]
) - Variants: responsive, pseudo, dark mode (class/media/both), RTL
- CSS variable theme support (theme values as CSS custom properties)
- Efficient CLI: npx/Node CLI for project-wide class extraction and CSS generation
- @apply and class extraction from HTML/JSX/Vue/Svelte
- Preflight: base styles with fine-grained control
npm install relaxcss --save-dev
# or
yarn add relaxcss --dev
npx relaxcss --out dist/output.css
- Scans your
src/
directory for all HTML, JS, TS, JSX, TSX, Vue, and Svelte files. - Extracts all class names and generates CSS for all used classes.
- Use
--watch
for watch mode (if implemented).
In your postcss.config.js
:
const relaxcss = require('relaxcss');
module.exports = {
plugins: [
require('postcss-import'), // must be first
relaxcss({
// custom config here
}),
require('autoprefixer'),
// ...
]
};
npx relaxcss --out dist/output.css
- By default, scans
src/**/*.{css,html,js,jsx,ts,tsx,vue,svelte}
. - Extracts all class names and @apply utilities.
- Generates CSS for all found classes.
- Supports custom config via
relaxcss.config.js
.
--out <file>
: Output CSS file (default:dist/output.css
)--watch
: Watch mode (auto-rebuild on file changes)--config <file>
: Path to custom config (default:relaxcss.config.js
)
const relaxcss = require('relaxcss');
module.exports = {
plugins: [
require('postcss-import'),
relaxcss({
// config options
}),
require('autoprefixer'),
]
};
RelaxCSS can be configured via a relaxcss.config.js
file or by passing an options object to the plugin.
Option | Type | Default | Description |
---|---|---|---|
theme |
Object | See below | Design tokens (colors, spacing, etc.) |
variants |
Object | See below | Responsive breakpoints, pseudo-classes |
plugins |
Array | [] | User utility plugins |
preflight |
Object | { enabled: true } |
Base styles, overrides, disables |
darkMode |
String | 'class' |
'class' , 'media' , or 'both' |
rtl |
Boolean | false |
Enable RTL logical property support |
fileExtensions |
Array | ["css","html","js","jsx","ts","tsx","vue","svelte"] |
Extensions to scan in CLI |
module.exports = {
theme: {
colors: {
primary: '#0070f3',
gray: {
100: '#f3f4f6',
900: '#111827',
},
},
spacing: {
1: '0.25rem',
2: '0.5rem',
4: '1rem',
},
// ...
},
variants: {
responsive: ['sm', 'md', 'lg', 'xl', '2xl'],
pseudoClasses: ['hover', 'focus', 'active', 'disabled'],
},
plugins: [
function({ addUtilities, config }) {
addUtilities({
'fancy-border': () => [
{ prop: 'border', value: '2px dashed magenta' },
],
});
},
],
preflight: {
enabled: true,
disableSections: ['box-sizing', 'list-style'],
overrides: 'body { background: #fafafa; }',
},
darkMode: 'class', // or 'media' or 'both'
rtl: false,
fileExtensions: ['html', 'js', 'jsx', 'ts', 'tsx', 'vue', 'svelte'],
};
theme
is an object of design tokens:colors
,spacing
,fontSize
,fontWeight
,lineHeight
,boxShadow
,zIndex
,opacity
,borderRadius
,borderWidth
,gridTemplateColumns
,gridTemplateRows
,flex
,transitionProperty
,transitionDuration
,transitionTimingFunction
,maxWidth
,maxHeight
, etc.- All theme values are exported as CSS custom properties (variables) for easy use in utilities and custom CSS.
module.exports = {
theme: {
colors: {
primary: '#0070f3',
gray: { 100: '#f3f4f6', 900: '#111827' },
},
spacing: { 1: '0.25rem', 2: '0.5rem', 4: '1rem' },
// ...
},
};
responsive
: Array of breakpoint keys (e.g.sm
,md
,lg
, ...)pseudoClasses
: Array of pseudo-class variants (e.g.hover
,focus
,active
, ...)
variants: {
responsive: ['sm', 'md', 'lg', 'xl', '2xl'],
pseudoClasses: ['hover', 'focus', 'active', 'disabled'],
}
darkMode
:'class'
(default),'media'
, or'both'
'class'
: Uses.dark
class for dark mode'media'
: Uses@media (prefers-color-scheme: dark)
'both'
: Supports both strategies
rtl
:true
orfalse
(default)- When enabled, logical properties (e.g.
margin-inline-start
) are used for margin/padding utilities, and direction-aware utilities are generated.
preflight.enabled
: Enable/disable base stylespreflight.disableSections
: Array of base style sections to disable (e.g.['box-sizing', 'list-style']
)preflight.overrides
: Custom CSS to inject at the top of the output
- Add custom utilities via the
plugins
array. - Each plugin is a function receiving
{ addUtilities, config }
. - Use
addUtilities({ 'class-name': (config) => [ { prop, value }, ... ] })
to register utilities.
plugins: [
function({ addUtilities, config }) {
addUtilities({
'fancy-border': () => [
{ prop: 'border', value: '2px dashed magenta' },
],
});
},
]
- Use square brackets for arbitrary values:
bg-[#222]
,p-[4px]
,w-[72vw]
, etc. - Works for colors, spacing, width, height, and more.
- Prefix classes with breakpoints or pseudo-classes:
sm:bg-blue-500
,hover:text-red-500
,dark:bg-black
,rtl:pl-4
. - Combine multiple variants:
sm:hover:bg-blue-500
,dark:focus:ring-2
.
- All theme values are exported as CSS custom properties (e.g.
--color-primary
,--spacing-4
). - Utilities use these variables for easy theming and overrides.
- RelaxCSS extracts all class names from your source files, including those used in
@apply
in CSS. - All used classes are included in the generated CSS.
- For production, use PurgeCSS to remove unused CSS.
- Example
postcss.config.js
:
const relaxcss = require('relaxcss');
const purgecss = require('@fullhuman/postcss-purgecss');
module.exports = {
plugins: [
require('postcss-import'),
relaxcss({ config: './relaxcss.config.js' }),
require('autoprefixer'),
purgecss({
content: [
'./public/**/*.html',
'./src/**/*.js',
'./src/**/*.jsx',
'./src/**/*.ts',
'./src/**/*.tsx',
'./src/**/*.vue',
],
defaultExtractor: content => content.match(/[^\s"'`<>]+/g) || [],
safelist: {
standard: ['body', 'html'],
greedy: [/^(sm:|md:|lg:|xl:|2xl:)/],
},
}),
],
};
// relaxcss.config.js
module.exports = {
plugins: [
function({ addUtilities, config }) {
addUtilities({
'btn-primary': () => [
{ prop: 'background', value: config.theme.colors.primary },
{ prop: 'color', value: '#fff' },
{ prop: 'padding', value: config.theme.spacing[2] },
],
});
},
],
};
<div class="bg-[#222] p-[4px] w-[72vw]"></div>
<div class="sm:bg-blue-500 hover:text-red-500 dark:bg-black rtl:pl-4"></div>
- Seamless integration: Works with any PostCSS-based build system (Webpack, Vite, Parcel, etc).
- Automatic class extraction: Processes your CSS and source files to generate only the CSS you use.
- Full feature set: All RelaxCSS features (JIT, plugins, variants, dark mode, RTL, CSS variables, etc) are available in plugin mode.
- Production ready: Combine with PurgeCSS and other PostCSS plugins for optimal output.
MIT