Skip to content

Release Notes

March 2026

Class sorting in PHP templates makes its long-awaited return, and Tailwind Typography goes CSS-only

Class sorting

I was somewhat surprised at how well class sorting worked in _tw with Tailwind 3, since my initial investigations had seemed to show that it wouldn’t be possible whatsoever. When it stopped working with Tailwind 4 because two of its dependencies stopped being updated, I reluctantly accepted it going away and worried it would be gone permanently.

But a few months ago the main dependency—eslint-plugin-tailwindcss—released a beta version with Tailwind 4 support, so I forked the other dependency, creating eslint-plugin-php-templates. (My assumption is that this plugin will end up only ever used by _tw, but who knows!)

Given the tentative nature of everything involved, I decided to use this setup on my own projects for a few months before releasing it. And I did find some bugs! But they were bugs that existing in the old implementation, too. So, having fixed those bugs, I’m confident this iteration of class sorting is more robust than the one that came before. But please let me know if you run into any issues!

CSS-only Tailwind Typography

Around a year ago, it seemed like Tailwind was close to launching an official CSS-only version of the Typography plugin.

That didn’t end up happening, but they did release a working branch. And since the CSS-only approach provides a lot of benefits for _tw, I forked that branch, replacing the existing Typography fork that _tw uses to improve WordPress block editor support.

The core benefits:

  • It’s now very easy to manage font weights via CSS variables in ./tailwind/tailwind-typography.css
  • There’s a straightforward way to add the entirety of the CSS from the Typography plugin into your theme and to modify it directly

The latter change creates an obvious path to going beyond adding prose classes to ./theme/functions.php when styling copy with Tailwind in the block editor.

Housekeeping

It’s been a while since my last release notes, so here are a few smaller, less exciting changes that kept things running smoothly:

Supporting Tailwind CSS IntelliSense

_tw has always supported Tailwind CSS IntelliSense, but support became a bit buggy in the Tailwind 4 transition. Because much more goes on in terms of auto-detection of configuration in Tailwind 4, I added a build process to generate tailwind-intellisense.css, which is structured to match exactly what IntelliSense is expecting.

Removing the asset URL workaround

There was a period of around six months, starting around one month after Tailwind 4 launched, when @tailwindcss/postcss started handling asset URLs (like for fonts or images) differently, but didn’t offer an option to override this behavior.

During that time, _tw used a search-and-replace approach to fixing the asset URLs, which was functional, but far from ideal.

After being petitioned by a number of people, me included, the Tailwind team added the transformAssetUrls option to @tailwindcss/postcss, allowing me to remove the search-and-replace code.

Ensuring build processes always run in development mode

For a year or two, I received intermittent bug reports saying that npm install doesn’t install anything, causing npm run dev (and all other build commands) to fail. Reporters were often using LocalWP, but I struggled to isolate the issue.

Eventually I knew that the problem was caused by LocalWP sometimes, but not always, setting NODE_ENV to production when running commands in its terminal. This eventually led to a solution that has completely eliminated these bug reports, unleashing confetti cannons throughout _tw headquarters. All it took was a .npmrc file in the project root with this line:

omit = nullCode language: plaintext (plaintext)

The more you know!

Simplifying zip file creation

Because the npm run bundle command creates a zip file that is versioned at build time, _tw needs a way to modify files as they’re being added to the zip without changing them in the file system. As this script evolved over time, two separate archiving packages were included, each handling different parts of the process.

One, archiver, has been minimally maintained, and it began throwing warnings on npm install. This motivated me to dig in a bit to see whether it would be possible to use ADM-ZIP alone to accomplish our goals (since we were already using it for part of the process).

It turns out it was possible, and now we have one fewer dependency and a very satisfying “found 0 vulnerabilities” message upon running npm install.


That’s it for now! Some of this work came out of attempting to make a video showing _tw in action, so that work will continue now that I’ve run out of improvements that I felt I needed to make when working on the video the first time around.