UnCSS Deployment & Usage Guide
Prerequisites
- Node.js: Version 12.0 or higher (required for async/await support used in the codebase)
- npm: Comes bundled with Node.js, or Yarn as an alternative
- HTML Files: Static HTML files, accessible URLs, or raw HTML strings to analyze
- CSS: Stylesheets linked in your HTML or specified manually
Installation
Global Installation (CLI Usage)
npm install -g uncss
Local Installation (Project-specific)
# As a development dependency
npm install --save-dev uncss
# Or for programmatic use
npm install uncss
Verify Installation
uncss --version
Configuration
UnCSS supports configuration via CLI flags, a .uncssrc file, or programmatic options.
Configuration File (.uncssrc)
Create a .uncssrc file in your project root (JSON format). Regex patterns are supported by wrapping in forward slashes:
{
"ignore": ["#added_at_runtime", "/test-[0-9]+/"],
"ignoreSheets": ["/fonts.googleapis/"],
"media": ["(min-width: 700px) handheld and (orientation: landscape)"],
"csspath": "../public/css/",
"htmlroot": "public",
"timeout": 1000,
"strictSSL": true,
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X)"
}
Key Configuration Options
| Option | Type | Description |
|---|---|---|
ignore | Array | Selectors to preserve (supports strings and regex patterns). Required for classes added by user interaction (hover, click) |
htmlroot | String | Project root for resolving root-relative URLs (e.g., /css/style.css) |
csspath | String | Relative path where CSS files are located |
timeout | Number | Milliseconds to wait for JavaScript evaluation (default: waits for load event) |
media | Array | Additional media queries to process beyond screen, all, and projection |
ignoreSheets | Array | Stylesheets to exclude from processing (supports regex) |
stylesheets | Array | Additional stylesheets to process beyond those found in HTML |
inject | Function/File | JavaScript to execute before UnCSS runs (useful for setting classes) |
Build & Run
Command Line Interface
Basic Usage (Output to stdout)
uncss https://example.com > cleaned.css
Process Local Files
# Single file
uncss index.html -o output.css
# Multiple files with glob patterns
uncss "src/**/*.html" -o dist/cleaned.css
# With specific stylesheets
uncss index.html -s css/bootstrap.css -s css/main.css -o output.css
Common CLI Patterns
# Ignore dynamic classes and set timeout
uncss index.html -i ".dynamic-class" -i "/^js-/" -t 2000 -o output.css
# Process with media queries and custom user agent
uncss index.html -m "(min-width: 700px)" -a "Mozilla/5.0" -o output.css
# Use config file
uncss index.html -u .uncssrc -o output.css
Node.js API
const uncss = require('uncss');
const fs = require('fs');
const files = ['index.html', 'about.html', 'https://example.com'];
const options = {
// Preserve selectors added by JS interaction
ignore: ['#added_at_runtime', /test-[0-9]+/],
// Handle root-relative paths
htmlroot: 'public',
// Custom injection before processing
inject: function (window) {
window.document.querySelector('html').classList.add('no-csscalc', 'csscalc');
},
// JSDOM options
jsdom: {
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X)'
},
// Additional stylesheets not in HTML
stylesheets: ['lib/bootstrap/dist/css/bootstrap.css'],
// Wait for JS execution
timeout: 1000
};
uncss(files, options, function (error, output) {
if (error) throw error;
fs.writeFileSync('cleaned.css', output);
});
Build System Integration
Gulp
const gulp = require('gulp');
const uncss = require('gulp-uncss');
gulp.task('css', function () {
return gulp.src('src/css/main.css')
.pipe(uncss({
html: ['index.html', 'posts/**/*.html'],
ignore: ['.dynamic-class']
}))
.pipe(gulp.dest('dist/css'));
});
Grunt
module.exports = function(grunt) {
grunt.initConfig({
uncss: {
dist: {
files: {
'dist/cleaned.css': ['index.html', 'about.html']
}
}
}
});
grunt.loadNpmTasks('grunt-uncss');
};
Handling Raw HTML
const rawHtml = '<html><head><style>.used { color: red; } .unused { color: blue; }</style></head><body><div class="used">Content</div></body></html>';
uncss(rawHtml, function (error, output) {
console.log(output); // Contains only .used rule
});
Deployment
CI/CD Integration
GitHub Actions
name: Build CSS
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Build HTML (if using templates)
run: npm run build:html
- name: Remove unused CSS
run: npx uncss dist/**/*.html -o dist/css/cleaned.css
- name: Deploy
run: # your deploy command
Netlify Build Command
# In netlify.toml or build settings
[build]
command = "npm run build && uncss dist/**/*.html -o dist/css/main.css"
publish = "dist"
Docker Usage
FROM node:18-alpine
RUN npm install -g uncss
WORKDIR /app
COPY . .
CMD ["uncss", "index.html", "-o", "output.css"]
Pre-commit Hook
# .husky/pre-commit or similar
#!/bin/sh
uncss src/index.html -o src/css/cleaned.css
git add src/css/cleaned.css
Troubleshooting
"Unused" CSS Not Being Removed
Problem: Classes added by JavaScript after page load (user interactions like clicks/hovers) are being removed.
Solution: Add these selectors to the ignore array:
{
"ignore": [".modal-open", ".dropdown-active", "/^js-/"]
}
Root-Relative URLs Not Found
Problem: CSS links like /css/style.css result in file not found errors.
Solution: Set the htmlroot option to your project root directory:
uncss index.html -H ./public -o output.css
JavaScript-Heavy Pages Timeout
Problem: UnCSS times out before JS finishes executing. Solution: Increase the timeout value:
uncss index.html -t 5000 -o output.css
SSL Certificate Errors
Problem: Errors when fetching external stylesheets over HTTPS. Solution: Disable strict SSL checking (not recommended for production):
{ strictSSL: false }
Template Files (PHP, ERB, etc.) Not Supported
Problem: UnCSS cannot parse .php or template files directly.
Solutions:
- Generate static HTML from templates first:
php -S localhost:8000 & uncss http://localhost:8000/index.php > output.css - Build your site to static HTML, then run UnCSS on the output.
Classes with Pseudo-selectors Removed Incorrectly
Problem: :hover, :focus, or ::before styles are missing.
Solution: UnCSS automatically strips these for selector matching, but if styles are missing, ensure the base selector exists in your HTML. If dynamically added, add to ignore.
Regex in .uncssrc Not Working
Problem: Ignore patterns not matching.
Solution: Ensure regex strings in .uncssrc start and end with /:
{
"ignore": ["/^col-(xs|sm|md|lg)-.*/"]
}