postcss-preset-env
Converts tomorrow's CSS syntax into code today's browsers understand by auto-selecting PostCSS polyfill plugins from your browserslist targets.
Repository Health
Technical Analysis
postcss-preset-env is a PostCSS plugin pack that lets teams write tomorrow’s CSS syntax today while shipping CSS that works in the browsers they actually target. It bundles well over a hundred individual PostCSS plugins — one per CSS feature tracked in the cssdb database — and automatically applies only the ones a project’s browserslist configuration actually needs, transforming custom media queries, nesting, color functions like oklch() and color-mix(), :is()/:has() selectors, and dozens of other emerging CSS features into equivalent code or safe fallbacks that older engines understand.
Under the hood it wraps Autoprefixer for vendor prefixing and exposes a stage option (0 experimental through 4 stable) plus a minimumVendorImplementations option that lets teams opt into features based on how many browser engines have actually shipped them, rather than spec maturity alone. Because it is a thin orchestration layer over community-maintained, single-purpose plugins from the csstools organization, individual features can also be enabled, disabled, or configured directly via the features option, giving fine control without losing the defaults most projects rely on.
What You Get
- Automatic feature detection - reads your
browserslistconfig (orenv/browsersoptions) and enables only the polyfills those browsers actually need. - Built-in Autoprefixer - vendor prefixes are applied using the same browser target list, so you don’t configure a separate prefixing step.
- Fine-grained feature control - the
featuresoption lets you force-enable, disable, or pass plugin-specific options to any of the 100+ individual CSS features by ID. - Stage-based and vendor-based opt-in - choose
stage(spec maturity, 0-4) orminimumVendorImplementations(how many browser engines ship it) to decide which not-yet-universal features to polyfill. - Client-side polyfill awareness - flags and optionally enables features (like
:has()or:focus-visible) that need a companion runtime polyfill alongside the CSS transform.
Common Use Cases
- Modern CSS in production today - use nesting, custom media queries, oklch()/color-mix() colors, and :is()/:has() selectors while still shipping CSS that works on your supported browser matrix.
- Consolidating a PostCSS pipeline - replace a hand-picked list of individual postcss-* plugins and autoprefixer with a single, centrally maintained pack.
- Framework and bundler integration - drop into Next.js, webpack, Vite/PostCSS Load Config, Gulp, or Grunt build pipelines with minimal configuration.
- Gradual migration to native CSS - as browser support for a feature improves, raise
minimumVendorImplementationsor reduce reliance on a polyfill without rewriting source CSS.
Under The Hood
Architecture
The package is a thin orchestration layer: src/index.ts exports a single PostCSS PluginCreator that initializes shared options, calls listFeatures(cssdb, options, sharedOptions, logger) from src/lib/list-features.mjs to resolve which of the 100+ cssdb-tracked features apply given stage/minimumVendorImplementations/browsers/env, maps the resolved features to their underlying postcss plugin instances via src/plugins/plugins-map.mjs and a generated plugins-data.json (built by scripts/generate-plugins-data.mjs from cssdb plus package.json dependencies), appends autoprefixer sharing the same browser target, and appends an internal OnceExit plugin for debug logging and help messages. Supporting modules (stage.mjs, prepare-features-list.mjs, format-feature.mjs, browsers-with-supports-stats.mjs) form a small functional pipeline — list, filter, format — that the main creator composes; changing this core feature-resolution abstraction would ripple through every consumer since it is the single source of truth mapping cssdb entries to actual plugin instances.
Tech Stack
A TypeScript entry point (index.ts, options.ts) sits atop internal logic written as plain ESM .mjs modules, compiled via a shared Rollup config at the monorepo root. Core runtime dependencies are autoprefixer, cssdb, and browserslist, plus dozens of individual @csstools/postcss-* and postcss-* polyfill packages declared as direct dependencies and dynamically composed, with postcss itself as a peerDependency. The monorepo uses TypeScript with strict settings, @microsoft/api-extractor/api-documenter for type and docs generation, ESLint with @stylistic/eslint-plugin, and knip for unused-export detection. Tests run on the native Node --test runner through a custom @csstools/postcss-tape fixture harness, with @stryker-mutator/core configured for mutation testing.
Code Quality
Tests live as fixture pairs (input CSS plus per-scenario expected-output CSS) driven by @csstools/postcss-tape, an approach well suited to a plugin whose job is transforming CSS into CSS, complemented by narrower unit coverage under src/test/lib and src/test/log. TypeScript covers the public option surface while internal implementation stays plain JavaScript, consistent with allowJs: true in the local tsconfig — strong typing at the boundary, more permissive internally. ESLint is enforced monorepo-wide and mutation testing via Stryker is configured specifically for this package, a notably rigorous signal beyond typical PostCSS plugins; CI runs through a GitHub Actions workflow referenced in the README badges. No obvious silent-failure patterns were found; errors largely propagate through PostCSS’s own mechanisms.
What Makes It Unique
Rather than hardcoding which CSS features to polyfill, the plugin computes the active set from real browser-support data (sourced from MDN and Can I Use via cssdb) intersected with the project’s browserslist target, and it offers two independent axes for opting into not-yet-universal features: spec stage versus minimumVendorImplementations, the latter tracking actual engine-implementation counts as a more empirical stability signal than W3C process stage alone. It is fundamentally a plugin-composition preset rather than an architecturally novel system, but the cssdb-driven auto-selection and the configurable logical writing-direction option are genuinely useful conveniences that hand-rolled PostCSS configs rarely replicate.
Used by 24 apps in this directory
Akaunting
Invoicing Finance
Open-source online accounting for small businesses and freelancers — invoices, expenses, and reporting without monthly fees or vendor lock-in.
Appsmith
Developer Tools · Automation · No Code Platforms
Open-source low-code platform to build admin panels, dashboards, and internal tools connected to any database or API.
Chatwoot
Customer Support
Open-source omnichannel customer support platform with AI-powered agents, live chat, and self-hosting — a full Intercom and Zendesk alternative.
CodeSandbox
Code Editors · Developer Tools
Instantly ready browser-based IDE that runs full npm dependency resolution and transpilation entirely client-side, with no server needed.
Element Web
Team Chat · Collaboration
A polished, self-hostable Matrix client for secure, decentralized messaging and collaboration that puts your organization in full control of its data.
ezBookkeeping
Invoicing Finance
Lightweight self-hosted personal finance manager with AI receipt scanning, multi-currency support, and MCP integration for complete data privacy.
Fleetbase
Logistics
Modular open-source logistics and supply chain operating system
Forem
Community · Blogging
Open source Ruby on Rails platform for building developer communities with articles, discussions, and social profiles—the same software that powers dev.to.
Laudspeaker
Marketing · Automation
Open-source customer engagement platform for building visual, event-triggered messaging journeys across email, SMS, push, in-app, and webhooks.