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:

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

By default, the plugin uses runtime mode. That is the most forgiving way to start: Master CSS reads classes in the browser, generates the required rules, and keeps working as your UI changes.

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

npm run dev

Choose the right mode

Runtime

Use runtime mode when you want the simplest integration and maximum flexibility. It is a strong default for SPAs, prototypes, internal tools, and applications where classes can appear after hydration.

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

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.

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 critical CSS stays inline in style#master-css. The page hydration manifest is externalized as a hashed JSON asset and referenced from data-master-css-hydration-manifest, so the HTML does not grow with the runtime handoff data.

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.

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:

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

Astro uses an integration:

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

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 runtime mode when you want speed and flexibility. Move to Static Rendering when your class graph is source-visible and you want compiled CSS. Use Pre-rendering when the HTML is already available at build time. Choose Progressive Rendering when you want the first page response to be styled early without giving up runtime behavior.

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.

  • Master UI


© 2026 Aoyue Design LLC.MIT License
Trademark Policy