No results

    Search failed

    npm GitHub

    PurgeCSS

    Sulphuris generates the full utility set โ€” every spacing step, every colour grade, every responsive variant โ€” so it is intentionally large before compression. A real project only ever uses a slice of it. Run PurgeCSS as a PostCSS plugin to scan your markup and remove every class you don't reference.

    Install

    npm install --save-dev postcss @fullhuman/postcss-purgecss

    Configure PostCSS

    Add PurgeCSS to your postcss.config.js. Point content at every file that can contain a class name โ€” templates, components, and any JS/TS that toggles classes.

    // postcss.config.js
    const purgecss = require('@fullhuman/postcss-purgecss').default
    
    module.exports = {
      plugins: [
        purgecss({
          content: [
            './**/*.html',
            './src/**/*.{js,ts,jsx,tsx,vue,svelte}',
          ],
          // Sulphuris classes use letters, digits and hyphens: p-16, col-lg-4,
          // bg-blue-500, d-md-none. This extractor keeps them intact.
          defaultExtractor: (content) => content.match(/[\w-/:]+(?<!:)/g) || [],
          safelist: {
            // Keep classes/attributes added at runtime and never seen in markup.
            standard: [/^is-/, /^has-/],
            // Dark-mode selector + the :root token block are not class-matched.
            greedy: [/data-color-scheme/],
          },
        }),
      ],
    }

    Run it

    Only run PurgeCSS for production builds โ€” during development you want the whole set available.

    Standalone (postcss-cli):

    npx postcss dist/sulphuris.css -o dist/sulphuris.min.css

    In a bundler โ€” Vite, webpack, and most toolchains pick up postcss.config.js automatically, so importing the compiled Sulphuris CSS is enough:

    import 'sulphuris/dist/sulphuris.css'

    Gate it on the environment so it never runs in dev:

    // postcss.config.js
    const purgecss = require('@fullhuman/postcss-purgecss').default
    
    module.exports = {
      plugins: [
        process.env.NODE_ENV === 'production' &&
          purgecss({ content: ['./**/*.html', './src/**/*.{js,ts}'] }),
      ].filter(Boolean),
    }

    Watch out for these

    PurgeCSS only keeps classes it can find as literal strings in your content. Anything assembled at runtime gets removed unless you safelist it.

    • Dynamically built class names. 'bg-' + color or `col-${n}` are invisible to the extractor. Write the full class literally, or safelist the family: safelist: [/^col-/, /^bg-(blue|red)-/].
    • Responsive & state variants. .d-md-none, .p-lg-24, :hover utilities are ordinary classes โ€” they survive only if the exact string appears in markup.
    • The --color-* tokens and dark mode. The :root custom-property block and the [data-color-scheme="dark"] overrides carry no class of their own. The greedy: [/data-color-scheme/] rule above keeps the dark-mode block; the :root block is a bare selector and is preserved by default. See [[design-tokens]].
    • Third-party / CMS markup. Add those templates to content, or safelist the utilities they rely on.

    When in doubt, safelist a whole family with a regex rather than losing classes at runtime โ€” it costs a few kB, a missing utility costs a broken layout.