npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@johnfmorton/critical-css-craftcms

v0.1.1

Published

Generate critical CSS for Craft CMS + Vite projects using Beasties

Readme

critical-css-craftcms

Generate critical CSS for Craft CMS projects that use the Craft Vite plugin by nystudio107. Uses Beasties for pure Node.js CSS extraction -- no Puppeteer or headless Chrome required.

A drop-in replacement for rollup-plugin-critical. Your existing config/vite.php stays the same -- the tool outputs critical CSS files in the exact format the Craft Vite plugin already expects (criticalPath and criticalSuffix). You only need to swap how the files are generated, not how they are consumed.

Install

npm install --save-dev @johnfmorton/critical-css-craftcms

Setup

1. Create a config file

Add critical-css.config.mjs to your project root:

export default {
  pages: [
    { uri: '/', template: 'index' },
    { uri: '/about', template: 'about/index' },
    { uri: '/services', template: '_pages/services' },
  ],
}

Each entry maps a URL path (uri) to a Craft template name (template). The template name determines the output filename -- about/index produces about/index_critical.min.css.

Add one entry per unique template layout. Pages sharing the same template only need one entry.

2. Set the environment variable

The CRITICAL_URL environment variable tells the tool where to fetch rendered HTML from. Add it to your .env:

CRITICAL_URL=https://your-site.ddev.site

3. Run

npx critical-css-craftcms

Or pass the URL inline:

CRITICAL_URL=https://your-site.ddev.site npx critical-css-craftcms

npm scripts

Add these to your package.json:

{
  "scripts": {
    "generate-critical": "critical-css-craftcms",
    "build:critical": "npm run build && critical-css-craftcms"
  }
}

Configuration Reference

All options except pages have defaults targeting a standard Craft CMS + Vite project structure.

| Option | Default | Description | |---|---|---| | pages | (required) | Array of { uri, template } objects | | outputDir | 'web/dist/criticalcss' | Output directory, relative to project root | | manifestPath | 'web/dist/.vite/manifest.json' | Vite manifest path, relative to project root | | appEntry | 'src/js/app.ts' | Key in the Vite manifest for the CSS entry | | publicDir | 'web' | Directory Beasties resolves CSS from, relative to project root | | publicPath | '/' | URL prefix that maps to publicDir | | beasties | { reduceInlineStyles: true, preload: 'none', fonts: true, logLevel: 'info' } | Beasties constructor options |

Full config example

export default {
  pages: [
    { uri: '/', template: 'index' },
    { uri: '/about', template: 'about/index' },
  ],
  outputDir: 'web/dist/criticalcss',
  manifestPath: 'web/dist/.vite/manifest.json',
  appEntry: 'src/js/app.ts',
  publicDir: 'web',
  publicPath: '/',
  beasties: {
    reduceInlineStyles: true,
    preload: 'none',
    fonts: true,
    logLevel: 'info',
  },
}

Programmatic Usage

import { generateCriticalCss } from '@johnfmorton/critical-css-craftcms'

const { results, successful, failed } = await generateCriticalCss({
  projectRoot: process.cwd(),
  baseUrl: 'https://your-site.ddev.site',
  outputDir: '/absolute/path/to/web/dist/criticalcss',
  manifestPath: 'web/dist/.vite/manifest.json',
  appEntry: 'src/js/app.ts',
  publicDir: 'web',
  publicPath: '/',
  pages: [
    { uri: '/', template: 'index' },
  ],
  beasties: {
    reduceInlineStyles: true,
    preload: 'none',
    fonts: true,
    logLevel: 'info',
  },
})

Craft CMS Integration

Vite Plugin Configuration

In config/vite.php, add the criticalPath and criticalSuffix settings:

<?php

use craft\helpers\App;

return [
  'checkDevServer' => true,
  'devServerInternal' => 'http://localhost:3000',
  'devServerPublic' => Craft::getAlias('@web') . ':3000',
  'errorEntry' => 'src/js/app.ts',
  'manifestPath' => Craft::getAlias('@webroot') . '/dist/.vite/manifest.json',
  'serverPublic' => Craft::getAlias('@web') . '/dist/',
  'useDevServer' => (bool) App::env('VITE_USE_DEV_SERVER'),
  'criticalPath' => '@webroot/dist/criticalcss',
  'criticalSuffix' => '_critical.min.css',
];

Twig Templates

In your base layout template (e.g., templates/_base/_layout.twig):

{{ craft.vite.includeCriticalCssTags() }}

This automatically matches the current template to its critical CSS file using the criticalSuffix naming convention.

Why Beasties over Puppeteer?

rollup-plugin-critical depends on Puppeteer, which downloads and runs a ~300MB headless Chromium binary. This creates CI/CD complexity, large dependency footprints, and fragile browser-based extraction.

Beasties analyzes HTML and CSS purely in Node.js with no browser process.

Troubleshooting

"No CSS files found in web/dist/"

Run your Vite build before generating critical CSS. The tool reads the compiled output.

"CRITICAL_URL environment variable is required"

Set it in your .env or pass it inline:

CRITICAL_URL=https://your-site.ddev.site npx critical-css-craftcms

"No critical CSS extracted" warning

Beasties couldn't match any CSS selectors to elements in the fetched HTML. Check that:

  • The URL is accessible and returns rendered HTML
  • The CSS file is being found (check console output)
  • The page has visible above-the-fold content

License

MIT