
Security News
Crates.io Implements Trusted Publishing Support
Crates.io adds Trusted Publishing support, enabling secure GitHub Actions-based crate releases without long-lived API tokens.
An exceptionally fast, thorough and tiny unused-CSS cleaner (MIT Licensed)
DropCSS is an exceptionally fast, thorough and tiny (~8 KB min) unused-CSS cleaner; it takes your HTML and CSS as input and returns only the used CSS as output. Its custom HTML and CSS parsers are highly optimized for the 99% use case and thus avoid the overhead of handling malformed markup or stylesheets, so you must provide well-formed input. There is minimal handling for complex escaping rules, so there will always exist cases of valid input that cannot be processed by DropCSS; for these infrequent cases, please start a discussion, use a previous, larger and slower 0.3.x version that uses heavier but more compliant parsers, or use an alternative CSS cleaner.
As a bonus, DropCSS will also remove unused any @keyframes
and @font-face
blocks, despite it being somewhat out of scope for this lib (being a purely intra-CSS optimization). Speaking of which, it's a good idea to run your CSS through a structural optimizer like clean-css, csso, cssnano or crass to re-group selectors, merge redundant rules, etc. It probably makes sense to do this after DropCSS, which can leave redundant blocks, e.g. .foo, .bar { color: red; }; .bar { width: 50%; }
-> .bar { color: red; }; .bar { width: 50%; }
if .foo
is absent from your markup.
A bit more on this project's backstory & discussions in /r/javascript and on Hacker News.
npm install -D dropcss
const dropcss = require('dropcss');
let html = `
<html>
<head></head>
<body>
<p>Hello World!</p>
</body>
</html>
`;
let css = `
.card {
padding: 8px;
}
p:hover a:first-child {
color: red;
}
`;
const whitelist = /#foo|\.bar/;
let dropped = new Set();
let cleaned = dropcss({
html,
css,
shouldDrop: (sel) => {
if (whitelist.test(sel))
return false;
else {
dropped.add(sel);
return true;
}
},
});
console.log(cleaned.css);
console.log(dropped);
The shouldDrop
hook is called for every CSS selector that could not be matched in the html
. Return false
to retain the selector or true
to drop it.
*
- universal<tag>
- tag#
- id.
- class
- descendant>
- child+
- adjacent sibling~
- general sibling[attr]
- attribute[attr=val]
[attr*=val]
[attr^=val]
[attr$=val]
:not()
:first-child
:last-child
:only-child
:nth-child()
:nth-last-child()
:first-of-type
:last-of-type
:only-of-type
:nth-of-type()
:nth-last-of-type()
test.html
document.querySelectorAll("*").length
styles.min.css
lib size w/deps | output size | reduction | time elapsed | unused bytes (test.html coverage) | |
---|---|---|---|---|---|
DropCSS |
52.6 KB 6 files, 1 Folders | 6.58 KB | 76.15% | 20ms | 575 / 8.5% |
UnCSS |
13.7 MB 2,831 Files, 301 Folders | 6.72 KB | 75.71% | 409ms | 638 / 9.3% |
Purgecss |
2.53 MB 513 Files, 110 Folders | 8.01 KB | 71.05% | 79ms | 1,806 / 22.0% |
PurifyCSS |
3.45 MB 791 Files, 207 Folders | 15.46 KB | 44.34% | 179ms | 9,440 / 59.6% |
Notes
A full Stress Test is also available.
.foo > ul + p:not([foo*=bar]):hover
will actually short circuit early if .foo
, ul
or p
are missing from the dom, and will never continue to structural/context or negation assertions. Tests must be carefully written to ensure they hit all the desired paths; it's easy to waste a lot of time writing useless tests that add no value. Unfortunately, even 100% cumulative code coverage of the test suite would only serve as a starting point. Good tests would be a diverse set of real-world inputs and manually verified outputs.<script>
tags; your HTML must be fully formed (or SSR'd). You should generate and append any additional HTML that you'd want to be considered by DropCSS. If you need JS execution, consider using the larger, slower but still good output, UnCSS
. Alternatively, Puppeteer can now output coverage reports, and there might be tools that utilize this coverage data to clean your CSS, too. DropCSS aims to be minimal, simple and effective.An+B
expression testing exactly right is frustrating. I got part-way there before discovering this tiny solution.FAQs
An exceptionally fast, thorough and tiny unused-CSS cleaner
We found that dropcss demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Crates.io adds Trusted Publishing support, enabling secure GitHub Actions-based crate releases without long-lived API tokens.
Research
/Security News
Undocumented protestware found in 28 npm packages disrupts UI for Russian-language users visiting Russian and Belarusian domains.
Research
/Security News
North Korean threat actors deploy 67 malicious npm packages using the newly discovered XORIndex malware loader.