CSS optimization library that removes unused CSS selectors from stylesheets
npx @tessl/cli install tessl/npm-purify-css@1.2.00
# PurifyCSS
1
2
PurifyCSS is a CSS optimization library that removes unused CSS selectors from stylesheets by analyzing HTML, JavaScript, and other content files. It intelligently detects which CSS selectors are actually used in your application and eliminates the unused ones, dramatically reducing file sizes while maintaining all necessary styles.
3
4
## Package Information
5
6
- **Package Name**: purify-css
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install purify-css`
10
- **CLI Installation**: `npm install -g purify-css`
11
12
## Core Imports
13
14
ES modules:
15
16
```javascript
17
import purify from "purify-css";
18
```
19
20
CommonJS:
21
22
```javascript
23
const purify = require("purify-css");
24
```
25
26
## Basic Usage
27
28
```javascript
29
const purify = require("purify-css");
30
31
// Basic usage with strings
32
const content = '<button class="button-active">Login</button>';
33
const css = '.button-active { color: green; } .unused-class { display: block; }';
34
const purifiedCSS = purify(content, css);
35
// Result: ".button-active { color: green; }"
36
37
// Usage with file patterns
38
const contentFiles = ['src/**/*.js', 'src/**/*.html'];
39
const cssFiles = ['src/css/*.css'];
40
const options = {
41
output: './dist/purified.css',
42
minify: true,
43
info: true
44
};
45
purify(contentFiles, cssFiles, options);
46
```
47
48
## Architecture
49
50
PurifyCSS operates through several key components:
51
52
- **Content Analysis**: Scans content files using glob patterns or direct strings to identify class names, IDs, and element selectors in use
53
- **CSS Parsing**: Uses the `rework` library to parse CSS into an Abstract Syntax Tree (AST) for precise selector manipulation
54
- **Selector Matching**: Employs intelligent word-based matching that can detect dynamically constructed class names and split selectors
55
- **Tree Walking**: Processes CSS rules recursively, including media queries and nested structures
56
- **Output Generation**: Generates clean CSS with optional minification using `clean-css`
57
58
## Capabilities
59
60
### CSS Purification
61
62
The core functionality that removes unused CSS selectors by analyzing content files and preserving only the selectors that are detected in use.
63
64
```javascript { .api }
65
/**
66
* Purify CSS by removing unused selectors based on content analysis
67
* @param {string|string[]} searchThrough - Content to analyze (file patterns or source strings)
68
* @param {string|string[]} css - CSS to purify (file patterns or source strings)
69
* @param {PurifyOptions} [options] - Configuration options
70
* @param {function} [callback] - Optional callback receiving purified CSS
71
* @returns {string|undefined} - Purified CSS string (if no callback) or undefined (if callback provided)
72
*/
73
function purify(searchThrough, css, options, callback);
74
75
interface PurifyOptions {
76
/** File path to write purified CSS output (default: false) */
77
output?: string | false;
78
/** Enable CSS minification using clean-css (default: false) */
79
minify?: boolean;
80
/** Log size reduction statistics to console (default: false) */
81
info?: boolean;
82
/** Log rejected selectors to console (default: false) */
83
rejected?: boolean;
84
/** Array of selectors to always preserve (supports wildcards) (default: []) */
85
whitelist?: string[];
86
/** Options to pass to clean-css minifier (default: {}) */
87
cleanCssOptions?: object;
88
}
89
```
90
91
**Content Input Formats:**
92
93
- **String**: Direct content to analyze for selector usage
94
- **Array of strings**: File patterns using glob syntax (e.g., `['src/**/*.js', 'src/**/*.html']`)
95
- **Mixed**: Can combine file paths and glob patterns in the same array
96
97
**CSS Input Formats:**
98
99
- **String**: Direct CSS source code to purify
100
- **Array of strings**: CSS file patterns using glob syntax (e.g., `['src/css/*.css']`)
101
- **Mixed**: Can combine file paths and glob patterns in the same array
102
103
**Usage Examples:**
104
105
```javascript
106
const purify = require("purify-css");
107
108
// Example 1: Direct strings
109
const htmlContent = '<button class="btn-primary">Click me</button>';
110
const cssContent = '.btn-primary { color: blue; } .unused { display: none; }';
111
const result = purify(htmlContent, cssContent);
112
113
// Example 2: File patterns with options
114
const contentPatterns = ['src/**/*.{js,html,php}'];
115
const cssPatterns = ['assets/css/*.css'];
116
const options = {
117
output: 'dist/purified.css',
118
minify: true,
119
info: true,
120
rejected: true,
121
whitelist: ['*modal*', 'dynamic-class']
122
};
123
purify(contentPatterns, cssPatterns, options);
124
125
// Example 3: With callback
126
purify(contentPatterns, cssPatterns, (purifiedCSS) => {
127
console.log('Purified CSS length:', purifiedCSS.length);
128
});
129
130
// Example 4: Callback with options
131
purify(contentPatterns, cssPatterns, options, (purifiedCSS) => {
132
// Process the purified CSS
133
console.log('Processing complete');
134
});
135
```
136
137
### Whitelist Support
138
139
PurifyCSS supports preserving specific selectors through whitelisting, with support for exact matches and wildcard patterns.
140
141
**Whitelist Patterns:**
142
143
- **Exact match**: `'button-active'` - Preserves any selector containing 'button-active'
144
- **Wildcard match**: `'*modal*'` - Preserves any selector containing 'modal' anywhere in the name
145
- **Element selectors**: `'body'`, `'html'` - Always preserved by default
146
147
```javascript
148
const options = {
149
whitelist: [
150
'button-active', // Exact match
151
'*modal*', // Wildcard - keeps any selector with 'modal'
152
'*tooltip*', // Wildcard - keeps any selector with 'tooltip'
153
'js-required' // Exact match - often used for JavaScript hooks
154
]
155
};
156
```
157
158
### CLI Interface
159
160
Command-line interface for CSS purification with file input/output support.
161
162
```bash { .api }
163
# Basic usage
164
purifycss <css-files> <content-files> [options]
165
166
# Options:
167
# -m, --min Minify CSS (boolean, default: false)
168
# -o, --out Output file path (string)
169
# -i, --info Show reduction statistics (boolean, default: false)
170
# -r, --rejected Show rejected selectors (boolean, default: false)
171
# -w, --whitelist Whitelist selectors (array, default: [])
172
# -h, --help Show help
173
# -v, --version Show version
174
```
175
176
**CLI Usage Examples:**
177
178
```bash
179
# Basic purification
180
purifycss src/css/main.css src/index.html
181
182
# Multiple files with output
183
purifycss "src/css/*.css" "src/**/*.{html,js}" --out dist/purified.css
184
185
# With minification and info
186
purifycss src/style.css src/app.js --min --info --out build/style.min.css
187
188
# With whitelist and rejected selector logging
189
purifycss src/style.css src/app.js --whitelist "*modal*" "dynamic-class" --rejected
190
```
191
192
### Intelligent Selector Detection
193
194
PurifyCSS uses advanced selector detection that can identify CSS class usage in various forms:
195
196
**Direct Usage:**
197
```html
198
<div class="button-active">Click me</div>
199
```
200
201
**Dynamic Construction:**
202
```javascript
203
// Split selectors
204
var half = 'button-';
205
$(button).addClass(half + 'active');
206
207
// Joined arrays
208
var dynamicClass = ['button', 'active'].join('-');
209
$(button).addClass(dynamicClass);
210
211
// Framework patterns (React example)
212
var classes = classNames({
213
'button-active': this.state.buttonActive
214
});
215
```
216
217
**Content Processing:**
218
- Scans all content through regex patterns to identify potential class names
219
- Handles JavaScript minification and compression for more accurate detection
220
- Supports multiple programming languages and template systems
221
- Automatically includes 'html' and 'body' selectors
222
223
## Types
224
225
```javascript { .api }
226
/**
227
* Configuration options for CSS purification
228
*/
229
interface PurifyOptions {
230
/** File path to write purified CSS to, or false to return as string */
231
output: string | false;
232
/** Enable CSS minification using clean-css */
233
minify: boolean;
234
/** Log information about file size reduction */
235
info: boolean;
236
/** Log the CSS selectors that were removed */
237
rejected: boolean;
238
/** Array of selectors to always preserve (supports wildcard patterns) */
239
whitelist: string[];
240
/** Options object passed to clean-css for minification */
241
cleanCssOptions: object;
242
}
243
244
/**
245
* Content input type - can be direct strings or file pattern arrays
246
*/
247
type ContentInput = string | string[];
248
249
/**
250
* CSS input type - can be direct CSS strings or file pattern arrays
251
*/
252
type CSSInput = string | string[];
253
254
/**
255
* Callback function receiving the purified CSS result
256
*/
257
type PurifyCallback = (purifiedCSS: string) => void;
258
```
259
260
## Error Handling
261
262
PurifyCSS handles various error conditions gracefully:
263
264
- **File read errors**: Logged as warnings but don't stop execution
265
- **Invalid JavaScript**: Falls back to uncompressed analysis if content compression fails
266
- **CSS parsing errors**: Handled by the underlying rework library
267
- **Glob pattern errors**: Invalid patterns are skipped with warnings
268
- **Permission errors**: File access issues are reported but don't crash the process
269
270
Common error scenarios:
271
272
```javascript
273
// File doesn't exist - logs warning but continues
274
purify(['nonexistent.js'], ['style.css']);
275
276
// Invalid CSS - parsing errors handled gracefully
277
const invalidCSS = '.broken { color: }';
278
purify('<div class="test">content</div>', invalidCSS);
279
280
// Invalid glob pattern - skipped with warning
281
purify(['src/**/*.{invalid'], ['style.css']);
282
```