The new Tailwind compiler is indeed quite fast, so you can use it for real-time SSR or something like that.
This example uses an existing @tailwindcss/node@next package,
but it seems setting up the compiler for a different runtime wouldn't be too difficult.
Check out the source code of @tailwindcss/node
# Install Tailwind v4 (experimental release)
npm i tailwindcss@next @tailwindcss/node@next
@import "tailwindcss";
/* Setup plugins and customize theme */
@plugin "daisyui" { /* for daisyui you need to use daisyui@alpha version */
name: "my-theme";
default: true;
prefersDark: false;
color-scheme: light;
--color-base-100: oklch(99% 0.02 240);
--color-base-200: oklch(97% 0.03 240);
--color-base-300: oklch(95% 0.04 240);
--color-base-content: oklch(20% 0.05 240);
}import { compile } from '@tailwindcss/node';
// First argument is your css config as a string
const compiler = await compile('@import "tailwindcss";', {
base: './',
onDependency() {}
});
/**
* @returns {string} Compiled css code
*/
export function compileTailwindcss(html: string) {
// Extract class names like "text-lg", "bg-purple-500", etc., from HTML
const candidates = parseClassNames(html);
return compiler.build(candidates);
}
const CLASSNAMES_REGEX =
/\b(?:class|className)\s*=\s*["']((?:\\.|[^"\\'])*)["']/g;
/**
* @description Parse unique class names from html
*/
function parseClassNames(html: string) {
return [
...new Set(
[...html.matchAll(CLASSNAMES_REGEX)].flatMap(
(match) => match?.[1]?.split?.(/\s+/) || []
)
),
];
}const renderedHtml = '<span class="text-xl">Hello World!</span>'
compileTailwindcss(renderedHtml);