Tue, April 22, 2025

Master CSS Vite: one plugin for every rendering mode

Aron
Aron
@aron1tw

Vite is one of the best foundations for modern frontend work: fast startup, predictable module graph, first-class plugins, and a build pipeline that is easy to extend without making the application feel heavy.

@master/css-vite brings Master CSS into that pipeline as a first-class Vite integration. Instead of choosing between several setup guides, manual runtime imports, scanning scripts, and HTML post-processing steps, you install one plugin and choose the rendering model that matches your application.

The goal is simple: keep Master CSS authoring as direct as markup, while letting Vite own the integration work.


One plugin, four rendering modes

The original Vite integration focused on Static Rendering. It worked well for projects that wanted a compiled stylesheet, but the rest of the Master CSS rendering story still required manual setup.

The new @master/css-vite plugin unifies the modes behind one entry point:

That matters because not every Vite app has the same shape. A design system playground, a documentation site, a SPA, and a partially pre-rendered app should not be forced into the same CSS delivery strategy.

Master CSS now lets the Vite project choose.


Install it

If you don't have a project yet, create one using npm create vite@latest my-app.

npm i @master/css-vite@rc

Then register the plugin:

vite.config.js
import { defineConfig } from 'vite'import masterCSS from '@master/css-vite' export default defineConfig({  plugins: [    masterCSS()   ]})

By default, the plugin uses static mode. Master CSS scans complete classes in source and emits ordinary CSS. CSS variables and native selectors remain dynamic in the browser; explicitly select runtime mode when new class names must be interpreted after the build.

Run the Vite dev server and start writing Master CSS classes:

npm run dev

Choose the right mode

Runtime

Use runtime mode when new class names must be interpreted in the browser, such as in visual editors or client-generated interfaces. Select it explicitly:

vite.config.js
import { defineConfig } from 'vite'import masterCSS from '@master/css-vite'export default defineConfig({  plugins: [    masterCSS({ mode: 'runtime' })  ]})

Static Rendering

Use static mode when your classes are visible in source and you want a compiled CSS asset before runtime. This is the closest mode to traditional utility-first build workflows.

vite.config.js
import { defineConfig } from 'vite'import masterCSS from '@master/css-vite'export default defineConfig({  plugins: [    masterCSS({ mode: 'static' })  ]})

Pre-rendering

Use pre-render mode when Vite emits HTML that can be styled before the browser runs JavaScript. The plugin renders the matching CSS and injects it into the document.

For rendered pages, the required CSS stays inline in style#master-css. Pre-render mode does not start a browser runtime or deliver a hydration manifest.

vite.config.js
import { defineConfig } from 'vite'import masterCSS from '@master/css-vite'export default defineConfig({  plugins: [    masterCSS({ mode: 'pre-render' })  ]})

Progressive Rendering

Use progressive mode when you want the first HTML response to carry the CSS it needs, while the runtime continues to support client-only state, late-rendered components, and dynamic UI.

vite.config.js
import { defineConfig } from 'vite'import masterCSS from '@master/css-vite'export default defineConfig({  plugins: [    masterCSS({ mode: 'progressive' })  ]})

This is the mode that best represents the Master CSS rendering model: render what can be known early, keep the runtime for what becomes known later.

In progressive mode, the runtime imports the page hydration manifest as a JSON module when it starts. Do not add a preload hint for that JSON file: the browser can already paint from style#master-css, and the manifest is only needed for the runtime to adopt those rules instead of rebuilding them.


What the plugin handles

@master/css-vite is not just a wrapper around an import. It participates in the Vite pipeline:

That is the difference between "Master CSS works in a Vite app" and "Master CSS feels like a Vite-native tool."


Built for Vite-powered frameworks

Vite is also the build foundation for many frameworks. @master/css-vite is the lower-level integration that makes the core Vite workflow work well, while framework packages can provide a more native setup when the framework has its own conventions.

Nuxt uses a module:

nuxt.config.ts
export default defineNuxtConfig({  modules: [    '@master/css-nuxt' // static by default    // ['@master/css-nuxt', { mode: 'progressive' }]    // ['@master/css-nuxt', { mode: 'runtime' }]    // ['@master/css-nuxt', { mode: 'pre-render' }]  ]})

Astro uses an integration:

astro.config.ts
import masterCSS from '@master/css-astro'export default defineConfig({  integrations: [    masterCSS() // 'static'    // masterCSS({ mode: 'progressive' })  ]})

A better default for Vite projects

The value of this release is not only that setup is shorter. It is that the rendering strategy is now explicit and local to the Vite config.

Start with the default Static Rendering when complete class names are visible in source. Choose Runtime Rendering when new class names appear in the browser, Pre-rendering when HTML is available before delivery, or Progressive Rendering when pre-rendered first-page CSS must hand off to a browser runtime.

That is the kind of choice a build tool should enable: one integration, multiple delivery strategies, and no extra application code when you change modes.

For full setup details, see the Vite installation guide and the rendering modes guide.


© 2026 Aoyue Design LLC.MIT License
Trademark Policy