Navigation

Integrations

Set up Master CSS in Vite

Connect Master CSS to Vite, React, Vue, React Router or TanStack Start, then verify static CSS and optional browser generation.

On this page

Add Master CSS to an application built with Vite, including React, Vue, React Router framework mode and TanStack Start. The integration generates CSS from complete class names in source. Keep the framework's existing Vite plugin and mount code; Master CSS joins that build through a shared stylesheet.

#Installation

  1. #Add Master CSS

    In an existing Vite project, run the installer from the project root with the --framework value from the framework table. Static is the default: complete class names in source become ordinary CSS.

    npm create @master/css@2.0.0 -- --framework vite --yes
  2. #Check the CSS entry

    The installer adds masterCSS() to the Vite plugins and updates the stylesheet listed under Framework entries. In a plain JavaScript starter, that is:

    src/style.css
    @import '@master/css';

    Keep this entry imported by the application. If the project uses a different filename, check the installer's output and keep the import pointed at that file. The installer does not create a framework application or replace its mount code.

  3. #Start using Master CSS

    For a plain JavaScript starter with an #app element, use this entry and run npm run dev. For a framework application, use its component example below instead.

  4. Check the installed styles

    src/main.js
    import './style.css'document.querySelector('#app').innerHTML = `  <p id="master-check" class="w-fit m(0) p-md b-solid b(1) b-line-divider r-md text-sm font-regular bg-surface-raised fg-text-strong">    Hello World  </p>`
    A neutral surface, a fine border, small corners and 1rem of padding on every side.

#Framework entries

Choose the installer value for your application. These are the conventional starter paths; React and Vue setups can reuse another supported existing CSS entry. Without the flag, the installer detects the framework from the project.

Framework--frameworkCSS entry
Vite with plain JavaScriptvitesrc/style.css
Reactreactsrc/index.css
Vuevuesrc/assets/main.css
React Router framework modereact-routerapp/app.css
TanStack Starttanstack-startsrc/styles/app.css

#React

In a React project built with Vite, replace src/App.tsx. Keep the src/index.css import in src/main.tsx.

src/App.tsx
export default function App() {  return (    <p id="master-check" className="w-fit m(0) p-md b-solid b(1) b-line-divider r-md text-sm font-regular bg-surface-raised fg-text-strong">      Hello World    </p>  )}

#Vue

In a Vue project, replace src/App.vue. Keep the src/assets/main.css import in the application entry.

src/App.vue
<template>  <p id="master-check" class="w-fit m(0) p-md b-solid b(1) b-line-divider r-md text-sm font-regular bg-surface-raised fg-text-strong">    Hello World  </p></template>

#React Router

In a React Router framework mode project, the installer imports app/app.css from app/root.tsx. Replace the home route and keep it registered in app/routes.ts. Retain Links, Scripts, Outlet and the document structure in app/root.tsx; they deliver the page and its stylesheet.

app/routes/home.tsx
export default function Home() {  return (    <p id="master-check" className="w-fit m(0) p-md b-solid b(1) b-line-divider r-md text-sm font-regular bg-surface-raised fg-text-strong">      Hello World    </p>  )}

#TanStack Start

In a TanStack Start project built with Vite, replace the index route. The installer imports src/styles/app.css from src/routes/__root.tsx, so every route loads the same CSS entry.

src/routes/index.tsx
import { createFileRoute } from '@tanstack/react-router'export const Route = createFileRoute('/')({  component: Home})function Home() {  return (    <p id="master-check" className="w-fit m(0) p-md b-solid b(1) b-line-divider r-md text-sm font-regular bg-surface-raised fg-text-strong">      Hello World    </p>  )}

#Check the setup

Change p-md to p-lg in the source while the dev server is running. Padding should grow from 1rem to 1.5rem. Restore p-md, then build the application:

npm run build

Serve the production output with the project's preview or start command. Plain Vite, React and Vue starters normally use npm run preview; React Router and TanStack Start use their configured server or deployment adapter. Check that the paragraph still has 1rem padding and that no Master CSS browser runtime is shipped in static mode.

Client-rendered applications need JavaScript to create the paragraph. For React Router or TanStack Start routes with server rendering enabled, disable JavaScript and reload to check that the server's HTML receives the same stylesheet.

If the file loads but one class is missing, keep its full name in source; see Scanning class names. If no utilities work, confirm the CSS entry is imported and the Vite configuration includes masterCSS() beside the framework plugin. If starter styles obscure the result, remove their appearance rules while keeping @import '@master/css';.


#Choose another rendering mode

Static mode is the default and needs no Master CSS startup code. Keep the CSS entry when changing modes:

FrameworkInstaller optionRuntime startup
Vite, React, Vue--mode runtimeInjected into index.html by the Vite plugin
React Router, TanStack Start--mode runtimeA browser-only import in the root route
Generate new classes in the browser

Run the installer with --mode runtime and your --framework value:

npm create @master/css@2.0.0 -- --framework vite --mode runtime --yes

For Vite, React and Vue, the plugin injects the runtime into index.html and emits its compiled program. Do not add a second runtime import.

React Router and TanStack Start produce their own HTML, which does not pass through Vite's index.html injection. Add a browser-only runtime import beside the stylesheet import in the existing root route, keeping its route definitions and component exports:

app/root.tsx
import './app.css'if (!import.meta.env.SSR) {  void import('virtual:master-css-runtime')}
src/routes/__root.tsx
import '../styles/app.css'if (!import.meta.env.SSR) {  void import('virtual:master-css-runtime')}

The guard keeps the virtual runtime out of server execution; load it once per document. Add the client types in a declaration file such as app/master-css.d.ts or src/master-css.d.ts:

/// <reference types="@master/css/client" />

Build and preview the app, then run this in the browser console. The paragraph should gain an underline without rebuilding:

document.querySelector('#master-check').classList.add('underline')

Server-rendered HTML does not include runtime-generated CSS before JavaScript runs. If the class has no effect, check the console and the emitted program request.

#Choose how to load a stylesheet

Keep the normal CSS import for a document stylesheet. Use a different request only when another consumer needs the CSS text or its URL. These requests do not replace the app's Master CSS entry or change its rendering mode.

RequestResult and responsibility
import './app.css'Vite loads the processed stylesheet for the document.
import styles from './Card.module.css'Vite loads scoped CSS and returns the local class-name mapping.
import css from './app.css?inline'Returns processed CSS text without injecting it; the consumer must attach it.
import source from './app.css?raw'Returns authored source, including any Master directives. It is not browser-ready CSS.
import href from './local.css?url'Returns a URL; attach it as a stylesheet link when the document needs those styles.

For example, insert trusted build output into a document you own:

import css from './app.css?inline'const style = document.createElement('style')style.textContent = cssdocument.head.append(style)

Processed text can still contain imports. Use CSSStyleSheet.replaceSync() only with import-free output; it does not load imported stylesheets. For a shadow root, follow the Lit setup, including its stylesheet order and asset-base requirements.

#Sass and CSS Modules

Keep the project's Sass dependency and Vite preprocessing options. Write the Master CSS entry import as a CSS URL import so Sass leaves it for Master CSS:

src/app.scss
@import url("@master/css");

Resolved Sass partials retain their resource directories. Source maps connect diagnostics to the original file where possible; generated or unmapped content can only identify a preprocessed location. Keep Master mixin definitions in .css, or use the Sass interoperability pattern.

CSS Modules retain their scoped exports and composes relationships. Native declarations can use the project's definitions without importing the global output again. Framework HMR or the consuming module must accept changed class-name exports to update them without a page reload. ?inline returns scoped CSS text; ?raw returns the original source. Vite 8.3.5 rejects ?url requests for .module.css and .module.scss; do not use that path for a module stylesheet.

#Check the deployed assets

Deploy the whole production output, including retained child stylesheets, images, fonts and any runtime program. Master CSS preserves import media, supports and layer qualifiers, and rewrites resource URLs from their original source owner. An inline string can therefore require separate assets too; the Imports contract explains the boundary.

For an SSR ?inline consumer, URLs use the configured public base. Vite does not emit SSR assets by default: deploy the matching client build's assets, or enable build.ssrEmitAssets when the server build must publish them. Inspect the served response and Network panel after moving the build to its deployment location; an in-place build cannot establish URL portability.

During development, deleting a referenced resource reports a compilation error; already published resource versions can remain available until that server context closes. Restore the dependency and confirm that its consumer updates and the error clears. A still-styled page alone does not prove that the latest compilation succeeded.