@opensourceframework/critters
v2.0.1
Published
Inline critical CSS and lazy-load the rest. Forked from GoogleChromeLabs/critters.
Maintainers
Readme
@opensourceframework/critters
Inline critical CSS and lazy-load the rest for faster page loads
This is a maintained fork of the original critters package by GoogleChromeLabs.
📢 Why This Fork?
The original critters package was archived by GoogleChromeLabs in October 2024. This fork continues maintenance to ensure the package remains available and up-to-date for the community.
What this fork provides:
- 🔄 Continued Maintenance: Ongoing updates and bug fixes
- 🔒 Security Updates: Prompt patches for vulnerabilities
- 🔧 Modern Tooling: Updated dependencies and build tools
- 🧪 Test Coverage: Comprehensive test suite
- 📖 Documentation: Improved and up-to-date documentation
Attribution
This package is a fork of GoogleChromeLabs/critters, originally created by:
- Jason Miller (@developit)
- Janicklas Ralph (@janicklas)
Original source code is Copyright 2018 Google LLC and licensed under the Apache License, Version 2.0.
Installation
npm install @opensourceframework/critters
# or
yarn add @opensourceframework/critters
# or
pnpm add @opensourceframework/crittersUsage
Basic Usage
import Critters from '@opensourceframework/critters';
const critters = new Critters({
path: '/path/to/public',
publicPath: '/'
});
const html = `
<html>
<head>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
`;
const processedHtml = await critters.process(html);With Webpack
// webpack.config.js
const Critters = require('@opensourceframework/critters');
module.exports = {
// ...
plugins: [
new Critters({
// Options
preload: 'swap',
pruneSource: false,
reduceInlineStyles: true
})
]
};With Next.js
// next.config.js
const Critters = require('@opensourceframework/critters');
module.exports = {
webpack: (config, { dev }) => {
if (!dev) {
config.plugins.push(
new Critters({
preload: 'swap'
})
);
}
return config;
}
};Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| path | string | process.cwd() | Base path for resolving stylesheets |
| publicPath | string | '' | Public URL prefix for stylesheets |
| external | boolean | false | Only inline styles from additionalStylesheets |
| additionalStylesheets | string[] | [] | Additional stylesheets to inline |
| preload | string | 'swap' | Preload strategy: 'swap', 'media', 'js', 'js-lazy', 'body', or 'none' |
| noscriptFallback | boolean | true | Add <noscript> fallback for preloaded stylesheets |
| inlineThreshold | number | 0 | Inline stylesheets smaller than this size (bytes) |
| minimumExternalSize | number | 0 | Minimum size for external stylesheets |
| pruneSource | boolean | false | Remove inlined rules from external stylesheet |
| mergeStylesheets | boolean | true | Merge multiple stylesheets into one |
| additionalStylesheets | string[] | [] | Fetch additional stylesheets not in the HTML |
| reduceInlineStyles | boolean | true | Reduce inline styles |
| loadFonts | boolean | true | Preload critical fonts |
| logger | object | null | Custom logger instance |
Preload Strategies
swap(default): Uses<link rel="preload">to load CSS asynchronouslymedia: Uses media attribute trick to load CSS asynchronouslyjs: Uses JavaScript to load CSS asynchronouslyjs-lazy: Uses JavaScript with requestAnimationFrame for lazy loadingbody: Appends stylesheet to body for async loadingnone: No preloading, just inlines critical CSS
How It Works
Critters extracts critical CSS by:
- Parsing the HTML document
- Finding all linked stylesheets
- Parsing CSS rules and matching them against DOM elements
- Inlining only the CSS rules that apply to elements in the initial HTML
- Lazy-loading the remaining CSS using your chosen preload strategy
Special CSS Comments
Control which CSS gets inlined using special comments:
/* critters:exclude */
.always-external { color: red; }
/* critters:include */
.always-inlined { color: blue; }
/* critters:include start */
.included-rule-1 { color: green; }
.included-rule-2 { color: yellow; }
/* critters:include end */critters:exclude- Never inline these rulescritters:include- Always inline these rules (even if not matched)critters:include start/critters:include end- Include a block of rules
Migration from critters
If you were using the original critters package, migrating is straightforward:
- import Critters from 'critters';
+ import Critters from '@opensourceframework/critters';
- const critters = new Critters(options);
+ const critters = new Critters(options);The API is fully compatible with the original package. Simply replace the package name in your dependencies and imports.
API Reference
new Critters(options)
Creates a new Critters instance.
critters.process(html)
Processes HTML and returns the result with inlined critical CSS.
- Parameters:
html(string): The HTML to process
- Returns:
Promise<string>- The processed HTML
critters.readFile(filename)
Reads a stylesheet file. Override this method to customize file reading.
- Parameters:
filename(string): The path to the stylesheet
- Returns:
string | undefined- The CSS content
Security
This package includes protections against:
- Path traversal attacks (stylesheets outside base path)
- HTML injection via CSS content
- Malicious media query injection
- Script injection via stylesheet URLs
Contributing
We welcome contributions! Please see our Contributing Guide for details.
License
Apache-2.0 © Google LLC
This fork is maintained by the OpenSource Framework Contributors.
