Integrations

Set up Master CSS in Express

Guide to setting up Master CSS in Express server-rendered templates.

Use progressive rendering when Express owns the HTML response. Express renders the template, @master/css-server injects the first-response CSS, and the Vite runtime asset adopts that CSS in the browser for later dynamic classes.

Open your project

Start from an Express project root.

Terminal
cd my-express-appnpm init -y

Install Master CSS

Install the server renderer, Vite, and the Vite integration.

Terminal
npm install express ejs @master/css@rc @master/css-runtime@rc @master/css-server@rc @master/css-preset@rcnpm install -D vite @master/css-vite@rc

Configure Vite

Build the browser runtime entry and base stylesheet into public/assets.

vite.config.ts
import { defineConfig } from 'vite'import masterCSS from '@master/css-vite'export default defineConfig({  plugins: [    masterCSS({ mode: 'runtime' })  ],  build: {    outDir: 'public/assets',    emptyOutDir: true,    rollupOptions: {      input: 'src/main.ts',      output: {        entryFileNames: 'app.js',        assetFileNames: 'app[extname]'      }    }  }})

Create the browser entry

Import the Vite-managed runtime and the Master CSS stylesheet.

src/main.ts
import { MasterCSSRuntime } from '@master/css-runtime'import manifest from 'virtual:master-css-manifest'import emittedGlobals from 'virtual:master-css-emitted-globals'import './app.css'const runtime = await MasterCSSRuntime.start({ manifest, emittedGlobals })runtime.observe()
src/app.css
@import "@master/css";

Render with Master CSS

Render the template first, then pass the full document to @master/css-server.

app.js
import express from 'express'import ejs from 'ejs'import { createServerRenderer } from '@master/css-server'import manifest from '@master/css-preset/default-manifest.json' with { type: 'json' }const app = express()const renderer = createServerRenderer({ manifest })app.use('/assets', express.static('public/assets'))app.get('/', async (_request, response) => {  const body = await ejs.renderFile('views/index.ejs')  const document = `<!doctype html><html lang="en"><head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width, initial-scale=1">  <link rel="stylesheet" href="/assets/app.css"></head><body>  ${body}  <script type="module" src="/assets/app.js"></script></body></html>`  const rendered = renderer.renderHTML(document, {    hydrationManifest: 'inject'  })  response.send(rendered.html)})const server = app.listen(3000)server.on('close', () => renderer.dispose())

Add build scripts

Build or watch the frontend assets beside the Express server.

package.json
{  "scripts": {    "build:assets": "vite build",    "watch:assets": "vite build --watch",    "start": "node app.js"  }}

Hello world

Now style your first server-rendered template using Master CSS syntax.

localhost:3000

Hello World

views/index.ejs
<h1 class="m-2xl italic font-5xl font-heavy text-neutral">  Hello World</h1>

Progressive rendering sends the first response with style#master-css, then the runtime adopts the injected hydration manifest and keeps handling classes added after the initial response. Use Express static rendering when templates contain complete class strings and you want a generated CSS asset instead.


© 2026 Aoyue Design LLC.MIT License
Trademark Policy