Custom PostCSS Plugins
Write your own PostCSS plugin to transform CSS nodes programmatically.
Custom PostCSS Plugins is a free CSS Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the CSS Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Write a Custom Plugin?
When no existing PostCSS plugin solves your need — a project-specific CSS transformation, migration helper, or custom lint rule — writing a custom plugin gives you direct access to the CSS AST.
Plugin Structure
A PostCSS plugin is a function that receives a Root node (the parsed CSS) and optionally a Result object. Use the postcss.plugin() factory or the modern direct function approach:
// my-plugin.js
const plugin = () => {
return {
postcssPlugin: 'my-plugin',
Declaration(decl) {
// Called for every declaration node
},
Rule(rule) {
// Called for every rule node
}
};
};
plugin.postcss = true;
module.exports = plugin;Walking Declarations
Transform every color declaration:
const plugin = () => ({
postcssPlugin: 'rem-converter',
Declaration(decl) {
if (decl.prop === 'font-size' && decl.value.endsWith('px')) {
const px = parseFloat(decl.value);
decl.value = `${px / 16}rem`;
}
}
});Adding New Rules
Inject a new rule after every .btn rule:
Rule(rule) {
if (rule.selector.includes('.btn')) {
const focusRule = rule.cloneAfter();
focusRule.selector = rule.selector + ':focus';
}
}Removing Declarations
Remove all color: red declarations (debug/cleanup plugin):
Declaration(decl) {
if (decl.prop === 'color' && decl.value === 'red') {
decl.remove();
}
}PostCSS Helpers
PostCSS provides helper methods on nodes:
node.remove(): removes the nodenode.replaceWith(newNode): replaces a nodenode.cloneBefore()/cloneAfter(): inserts a clonepostcss.decl()/rule()/atRule(): creates new nodes
Async Plugins
PostCSS plugins can be async — useful when you need to read files or make network requests:
async Declaration(decl, helpers) {
if (decl.prop === 'icon') {
const svg = await readFile(`icons/${decl.value}.svg`);
decl.replaceWith(helpers.decl({ prop: 'background', value: `url(${svg})` }));
}
}PostCSS Plugin Testing
Test plugins using the postcss package directly:
const postcss = require('postcss');
const plugin = require('./my-plugin');
test('converts px to rem', () => {
const input = 'p { font-size: 16px; }';
const result = postcss([plugin()]).process(input, { from: undefined });
expect(result.css).toBe('p { font-size: 1rem; }');
});Plugin Options
Accept configuration options by taking an argument in the plugin factory:
const plugin = (opts = {}) => ({
postcssPlugin: 'configurable',
Declaration(decl) {
if (decl.prop === opts.property) {
decl.value = opts.replacement;
}
}
});Publishing PostCSS Plugins
PostCSS plugins follow a naming convention: postcss-plugin-name. They are published to npm and added to the PostCSS repository. For internal tools, keep them as local files in your project.
Quick Check
Which PostCSS visitor is called for every CSS property: value pair in the stylesheet?
Recap
Custom PostCSS plugins use visitor methods to process CSS AST nodes. Declaration(decl) for property:value pairs, Rule(rule) for selector blocks, AtRule() for @-rules. Use node methods like remove(), replaceWith(), and cloneAfter() to modify the CSS tree. Test plugins with the postcss package directly.
Frequently asked questions
Is the “Custom PostCSS Plugins” lesson free?
Yes — the full text of “Custom PostCSS Plugins” is free to read here on the web, and the CSS Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the CSS Academy course, upgrade to CoddyKit PRO.
What will I learn in “Custom PostCSS Plugins”?
Write your own PostCSS plugin to transform CSS nodes programmatically. You practise CSS Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start CSS Academy?
No prior experience is required. CSS Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Custom PostCSS Plugins” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this CSS Academy lesson?
Yes. Every CSS Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- What PostCSS Does and How It Works
- Autoprefixer and cssnano
- Custom PostCSS Plugins
- PostCSS in Vite and Webpack