PostCSS 8.0 brings new plugin API, node_modules
size reduction, better source map support, and CSS parser improvements.
Check out a day-by-day diary of PostCSS 8.0 development process.
See Migration Guides for end-users and for plugin developers.
Thanks to Sponsors
With more than 100 M downloads per month, it becomes hard to support PostCSS in free time. For instance, getting the 8.0 release ready took 4 months of work.
This release was possible thanks to out community. Tailwind CSS, De Voorhoede, InVision AG, Brainbow, and many individual contributions.
If your company wants to support the sustainability of front-end infrastructure or just wants to give some love to PostCSS, you can join our supporters by:
- Tidelift with a Spotify-like subscription model and supporting all projects from your lock file.
- Direct donations in PostCSS & Autoprefixer Open Collective.
Breaking Changes
We try to avoid any breaking changes for end-users:
- PostCSS 8 dropped Node.js 6.x, 8.x, 11.x, and 13.x versions support. All these versions have no security updates anymore.
- We now serve ES6+ sources in the npm package without Babel compilation. If you are creating tools like CodePen and put PostCSS into the client-side JS bundle, you may need to run Babel on
node_modules/postcss
for old browsers. - We removed rarely used
postcss.vendor
API.
New Plugin API
The biggest change in PostCSS 8 is a new plugin API. Thanks to @BondarenkoAlex for big help in creating a new API.
module.exports = () => {
return {
postcssPlugin: 'postcss-will-change',
Declaration: {
'will-change': (decl, { Declaration }) => {
decl.cloneBefore(
new Declaration({ prop: 'backface-visibility', value: 'hidden' })
)
}
}
}
}
module.exports.postcss = true
We know that rewriting old plugins will take time, but the new API will improve the end-user’s experience and make life easier for plugin developers:
- With new API, all plugins can share a single scan of the CSS tree. It makes CSS processing up to 20% faster.
- Because npm often duplicates dependencies, you may have many
postcss
duplicates in yournode_modules
. New API fixes this problem. - Plugins will re-visit changed nodes to reduce compatibility issues between plugins. Now the order of plugins in your PostCSS config will be less important.
- New API is close to Babel’s visitor API.
These resources will help plugin developers in API migration:
- The Migration Guide
- Writing a PostCSS Plugin
- We have a Gitter chat open for all questions related to plugin migration.
PostCSS development guidelines were also changed:
- Now it is prohibited to create own AST on top of PostCSS AST classes since it could lead to painful bugs due to the usage private APIs.
- Plugins and runners must have
postcss
inpeerDependencies
.
New Website without React
Previously PostCSS used a React-based framework for the project's website. Since we have a static website, we decided to migrate to a React-free framework and got good performance improvements:
- 360 → 20 ms for Max Potential First Input Delay
- 3.3 → 1.5 seconds for First CPU Idle
- 3.3 → 1.5 seconds for Time to Interactive
Check out postcss.org and new API docs that feature the awesome alchemy-inspired design by @okonet.
We also removed Google Analytics tracking scripts and encourage other open source projects to be an example in caring about user’s privacy and performance.
Parser Improvments
Did you know that all examples below are valid CSS?
:root {
--empty: ;
--JSON: [1, "2", {"three": {"a":1}}, [4]];
--javascript: function(rule) { console.log(rule) };
}
@supports (--element(".minwidth", { "minWidth": 300 })) {
[--self] {
background: greenyellow;
}
}
Now PostCSS parses even those rare edge cases correctly. Thanks to Tailwind CSS and Prettier teams for adding more cases to our CSS parser tests collection.
Note that now --roundMixin: { border-radius: 8px }
will be parsed as a Declaration
with the { border-radius: 8px }
value.
Better Source Map Support
We have added support for two new source map formats: Index map and JSON (data:application/json
).
PostCSS 8 is now much closer to the source map spec. Thanks to the Google team for reports:
- We now treat
sources
in map as URLs instead of file paths. - We now resolve
sources
relative to map file, not CSS file.
A few source map APIs were added:
opts.maps.absolute = true
option for absolute paths in source map.opts.maps.annotation = (file, root) => url
for a dynamic path to source map.Node#origin()
now returnsposition.url
in addition toposition.file
for compatibility with absolute URLs in source map’ssources
.
API Changes
We have added ES modules support and now we export all classes from the main entry:
import { CssSyntaxError, parse } from "postcss"
@graberzz added Node#source.offset
in addition to line
and column
.
CSS Custom Properties and Sass-like $
-variables now have a special Declaration#variable
mark:
const root = parse(`
:root {
--propery: value;
}
$variable: value
`)
root.first.first.variable //=> true
root.last.variable //=> true
TypeScript
PostCSS now has a first-class TypeScript support:
- We moved API docs from JSDoc to TypeDoc. Check out our new API docs.
- We are using check-dts to test types with special unit tests.
- We keep types in separate files for better readability.
- With the new structure and test system, we fixed many small issues in types.
Other Changes
- Fixed calling
replaceWith
with input replaced node (by @josephkaptur). - Reduce dependencies by replacing
chalk
tocolorette
. - Added
Declaration#value
auto-conversion to string to prevent plugin’s bugs. - Fixed building PostCSS with Rollup (by @mapgrid) because of circular dependencies.
- Moved unknown source from counter to random IDs:
<input css 9M4X8l>:10:6
. - Removed docs from the npm package.