Skip to main content

The First PostCSS Commit Landed on September 7, 2013

Andrey Sitnik pushed the initial commit to the PostCSS repository on September 7, 2013. The message was about as unglamorous as it gets: init project. The public release came a couple of months later in November. Six months before that, nobody involved had any intention of building a CSS tool at all. The whole thing started as an emergency exit from a different library.

The context is Rework, a modular CSS processor by TJ Holowaychuk. Rework's idea, committed in September 2012 and written up publicly in February 2013, was that CSS preprocessing did not have to be a monolithic language like Sass or Less. You could expose the parsed stylesheet as a plain object tree and let small plugins transform it. Sitnik was doing front end work for Evil Martians at the time and needed vendor prefixes generated from real browser data. On March 14, 2013 he started a Rework plugin for exactly that, initially called rework-vendors, renamed to Autoprefixer two weeks later.

Autoprefixer grew faster than Rework could accommodate. Prefixing needs to know exactly where a declaration sat in the source, how it was formatted, and how to insert siblings without shuffling whitespace and comments, because the output is read by humans as often as by browsers. Rework's parsed representation could not carry that information reliably, and patching around it would have meant forking. So Sitnik started over with a parser he controlled, one that kept source positions, preserved raws, and could regenerate CSS that looked like the input. That is the commit from September 7.

The architecture that emerged is almost aggressively boring, and that is the point. PostCSS is a CSS parser that produces an abstract syntax tree, a set of classes describing that tree, a stringifier that turns the tree back into CSS, and a source map generator. There is no preprocessor built in, no variables, no nesting, no mixins. Every feature you associate with PostCSS is a plugin walking the tree: Autoprefixer for prefixes, cssnano for minification, stylelint for linting, postcss-preset-env for future syntax, CSS Modules for scoped selectors, and Tailwind CSS, which is itself a PostCSS plugin that generates utility classes from your config and your content scan. A minimal plugin is roughly a dozen lines: subscribe to a node type, inspect it, mutate it.

The timeline shows how quickly the bet paid off. The first third party plugin, grunt-pixrem, appeared in December 2013, three months after the initial commit. Autoprefixer 1.0 migrated off Rework and onto PostCSS before the end of that same month, which immediately gave the new parser a real user with real bug reports. Everything else followed from having a stable plugin interface early: once plugin authors can rely on the AST not changing shape, an ecosystem compounds.

The project also has a personality that most build tools lack. PostCSS version codenames come from the Ars Goetia, the catalogue of demons in the Lesser Key of Solomon, so version 1.0.0 is Marquis Decarabia and later releases carry equally obscure names. The logo is the alchemical symbol for the philosopher's stone, chosen because the project's stated theme is alchemy, transforming one thing into another. Sitnik has also publicly retired a piece of his own vocabulary: the team originally called PostCSS a postprocessor, then admitted in 2015 that the term was a mistake because it implied the tool ran after some other pipeline. The word now is processor, which is more accurate and less arguable.

The practical lesson from that September commit is about scope. PostCSS did not try to be Sass. It tried to be the thing Sass, Less, and every other CSS tool could be built on, and it won a large share of the front end build chain by being the smallest possible layer that still had an opinion about correctness. If you have ever debugged a plugin ordering problem, where postcss-import has to run before Tailwind and Autoprefixer has to run last, you have felt both the strength and the weakness of that design: composable pieces, and the responsibility to assemble them in the right order.

We use cookies for ads and analytics.