TailwindPlugin
TailwindPlugin transforms computed color and typography tokens into CSS. It generates the static @theme block (Tailwind build-time) and the dynamic @layer theme block (runtime, scoped to .dynamic).
When using defineConfig from @udixio/tailwind, TailwindPlugin is wired automatically — you never instantiate it directly. All options are passed flat into defineConfig. This page covers the internals.
Direct instantiation
import { FontPlugin, loader } from '@udixio/theme';
import { TailwindPlugin } from '@udixio/tailwind';
const api = await loader({
sourceColor: '#6750A4',
plugins: [
new FontPlugin(),
new TailwindPlugin({ darkMode: 'class', darkSelector: '.dark' }),
],
});
await api.load();
const css = api.plugins.getPlugin(TailwindPlugin).getInstance().outputCss;Generating the static CSS programmatically
generateStaticThemeCss(config) returns, as a string, exactly what the udixio-theme CLI and the bundler plugins write to udixio.generated.css — without touching the filesystem. Use it from your own build script when neither fits (custom pipelines, several themes emitted at once):
import { writeFileSync } from 'node:fs';
import { generateStaticThemeCss } from '@udixio/tailwind';
import config from './theme.config';
writeFileSync('src/udixio.generated.css', await generateStaticThemeCss(config));An optional second argument (api) => void runs before the load, for palette or context overrides. For the colors-only CSS used at runtime / SSR, use generateThemeCss from @udixio/ui-react instead.
Options reference
| Option | Type | Default | Description |
|---|---|---|---|
darkMode | 'class' | 'media' | 'class' | Dark mode strategy |
darkSelector | string | '.dark' | CSS class/selector that activates dark mode |
dynamicSelector | string | '.dynamic' | Selector that receives live CSS variables |
subThemes | Record<string, string | Color | number> | — | Named color variants (see Sub-themes) |
responsiveBreakPoints | Record<string, number> | { lg: 1.125 } | Additional Tailwind breakpoints |
outFile | string | udixio.generated.css | Output path for the generated stylesheet in Node/CLI mode |
resetColors | boolean | true | Reset Tailwind’s default color namespace before emitting theme colors |
ssr | boolean | false | Emit browser-compatible CSS without filesystem writes |
CSS structure
The plugin generates three distinct blocks on every api.load():
/* 1. Static — Tailwind build-time values */
@theme {
--color-primary: #6750a4;
--color-surface: #fffbfe;
/* … all tokens */
}
/* 2. Dynamic light — runtime, scoped to .dynamic */
@layer theme {
.dynamic {
--color-primary: #6750a4;
--color-surface: #fffbfe;
}
}
/* 3. Dynamic dark — runtime, scoped to .dark .dynamic */
@layer theme {
.dark .dynamic,
.dark.dynamic {
--color-primary: #d0bcff;
--color-surface: #1c1b1f;
}
}For darkMode: 'media', block 3 uses @media (prefers-color-scheme: dark) instead of a class selector.
dynamicSelector
The dynamic selector is the scope boundary for runtime updates. Only elements inside .dynamic (or whatever value you configure) receive live variable updates when ThemeProvider reinjects the <style> tag.
new TailwindPlugin({ dynamicSelector: '.my-app' });<div class="my-app">
<!-- lives in the live-update scope -->
</div>Elements outside this selector still get Tailwind values from the static @theme block, but those reflect the build-time snapshot only.
responsiveBreakPoints
Adds custom breakpoints to the generated CSS:
new TailwindPlugin({
responsiveBreakPoints: {
'3xl': 1920,
tablet: 768,
},
});outFile
In non-browser environments, outFile controls where the generated stylesheet is written. Relative paths are resolved from the current working directory. The plugin writes the generated file; it does not append to an existing stylesheet.
new TailwindPlugin({
outFile: './src/styles/udixio.generated.css',
});Accessing output from onLoad
class MyPlugin extends PluginImplAbstract<{}> {
onLoad() {
const tw = this.api.plugins.getPlugin(TailwindPlugin).getInstance();
console.log(tw.outputCss); // the full generated CSS string
}
}