遷移

Migrating from CSS and CSS Modules

Move global CSS and CSS Modules toward Master CSS where class strings, tokens, or composition make the result easier to maintain.

Regular CSS and CSS Modules can coexist with Master CSS for as long as the project needs. Treat migration as a cleanup pass, not a rule that every declaration must become a class.

Move repeated, visual, markup-owned styles into Master CSS classes. Keep global resets, vendor styles, complex selectors, generated CSS, and hard-to-read one-off rules in regular CSS.


Migration strategy

Start with the stylesheet your app already loads.

  1. Import @master/css from the app CSS entry.
  2. Keep default source discovery unless the project needs a narrower scan boundary.
  3. Move shared design values into @theme.
  4. Convert component-local visual rules into class strings when the markup stays readable.
  5. Use @reference and @compose inside CSS Modules when a local class name is still the clearest API.
  6. Delete old CSS only after the affected screens build and visually match.

Avoid converting selectors that describe document structure, third-party internals, browser quirks, or animation timelines better than a class list can.


Audit checklist

Inspect the CSS surface before changing files.

AreaWhat to look forMigration decision
App CSS entryGlobal imports, reset files, cascade layers, and framework CSS entriesAdd Master CSS beside the existing CSS first.
Global CSSBase element styles, custom properties, fonts, media queries, and layout primitivesKeep broad document rules in CSS; move reusable values into @theme.
CSS Modules.module.css files, styles.* usage, :global, composes, and local variantsConvert to markup classes or use @compose inside the module.
Tokens--* custom properties, theme files, spacing scales, color variables, and breakpointsMove project-owned values into Master CSS @theme blocks.
Dynamic valuesInline styles, CSS variables, runtime-calculated measurements, and data attributesKeep the class static and pass dynamic values through CSS variables.
External CSSVendor styles, generated CSS, editor themes, maps, and third-party component stylesKeep as CSS unless the project owns the styling contract.

Add Master CSS beside existing CSS

Keep the current CSS files loaded while Master CSS starts generating rules for new or converted markup.

@import "@master/css";

Default source discovery is enough for most projects. Add @source, @source not, @safelist, or @blocklist only when the migration needs explicit scan boundaries or classes that are not present as complete source strings.

Use Rendering modes to decide whether the project should use static rendering, runtime rendering, or progressive rendering before converting many files.


Convert local CSS to markup classes

Move local visual declarations into markup when the class list is easier to review than a separate selector.

.card {    display: grid;    gap: 1rem;    padding: 1.5rem;    border-radius: .75rem;    background: var(--color-surface);}
export function Card({ children }: { children: React.ReactNode }) {    return (        <section className="grid gap:md p:lg r:lg bg:surface">            {children}        </section>    )}

Prefer named theme tokens such as bg:surface, p:card, or r:card when the value is a product decision. Prefer direct native declaration classes such as scroll-margin-top:4rem when the CSS property is clearer than inventing a new abstraction.


Keep CSS Modules when they are the component API

CSS Modules are still useful when a component exposes a stable local class name, needs selectors that target internal structure, or composes shared styles with a local variant.

Use @reference to make project tokens, components, utilities, and custom variants available without importing the app CSS output again.

@reference "../app.css";.button {    @compose inline-flex align-items:center justify-content:center gap:xs h:10x px:md r:md bg:blue-60 fg:white;}.button:disabled {    @compose opacity:.5 pointer-events:none;}
import styles from './Button.module.css'export function Button(props: React.ButtonHTMLAttributes<HTMLButtonElement>) {    return <button className={styles.button} {...props} />}

Use this pattern when removing the module would force too many call sites to change at once. Convert the module away later if the local class stops adding value.


Move shared values into @theme

Project-owned custom properties usually belong in @theme before large-scale class conversion. That lets markup use token names instead of hard-coded values.

@import "@master/css";@theme {    --color-surface: #ffffff;    --color-body: #172033;    --spacing-card: 1.5rem;    --radius-card: .75rem;}
<article class="bg:surface fg:body p:card r:card grid-cols:3@md">    ...</article>

Keep plain CSS custom properties when the value is runtime-owned, component-private, or intentionally outside the design system.

<div className="w:$progress bg:blue-60" style={{ '--progress': `${value}%` } as React.CSSProperties} />

Validate the migration

Review each batch as both code and UI.

  • Run the project's formatter, linter, type check, tests, and production build.
  • Use Code linting to validate Master CSS class strings.
  • Compare migrated screens in light mode, dark mode, responsive breakpoints, hover and focus states.
  • Keep CSS for selectors, animations, and vendor output that would become harder to understand as class strings.
  • Remove old CSS only after no component or page still depends on it.

Useful references

  • Master UI


© 2026 Aoyue Design LLC.MIT License
Trademark Policy