Migration

Migrating from Master CSS v2 RC

Upgrade a pre-change v2 RC project to named tokens, native declarations, explicit CSS units, and the v2 binding contract.

This guide upgrades six saved RC contracts to language v3 (an internal contract number, not the product version): rc-legacy before named tokens, rc-named before explicit modes and native queries, rc-native before the native-value boundaries, simple-query subset and deterministic source lifecycle, rc-managed before native components and ordered composition, rc-utilities before fixed raw intent and whole-definition replacement, and rc-sizing before entry ownership fixes and preset sizing removal. Check the exact installed RC versions and resolved manifest first; RC releases did not all have identical behavior. Follow stages 2–7 for applicable earlier changes, then the boundary, native-component and utility stages below.

Save the old generated CSS and browser results first. Upgrade related packages, native/Wasm artifacts, manifests, hydration output, and source syntax as one coordinated change. Do not initialize the old and new Master runtimes on the same page.

Back to migration frameworks.


1. Inventory and save the RC baseline

  • Record the installed versions of core, preset, compiler, runtime, server, framework integrations, language tooling, ESLint, and custom bindings.
  • Save the resolved RC manifest, its source CSS entries and imports, and the effective base-unit and root-size settings. A failed settings lookup is not permission to assume defaults.
  • List custom tokens, inline tokens, modes, namespace fallbacks, managed utilities, variants, and component definitions.
  • Find classes in templates, class builders, @compose, safelists, blocklists, test fixtures, and selectors in CSS or JavaScript. Include classes supplied by dependencies and generated content.
  • Record static, server, runtime, and progressive rendering paths, including hydration manifests, CSS asset URLs, and cached pages.
  • Save generated declarations and representative screenshots or computed styles at relevant breakpoints and themes. Include font metrics, background layers, border styles, outlines, and SVG strokes.

Keep the original baseline available throughout migration. Rebuilding an RC manifest with the new engine cannot reconstruct the old overload decisions.


2. Separate names from direct values

A hyphen selects a named token or utility. A colon passes a CSS value. Aliases replace property names; they do not infer another property from a value.

The RC column below is historical reference text, not executable new syntax. brand, md, and similar names refer to tokens from the original project; retain their identities rather than substituting whichever token happens to have the same current value.

RC referenceNew syntaxGenerated declaration or semantic change
font:monofont-monofont-family:var(--font-family-mono)
font:boldfont-boldfont-weight:var(--font-weight-bold)
font:smfont-smfont-size:var(--font-size-sm)
text:smtext-smRetains font size, calculated line height, and letter spacing.
fg:brandfg-brandcolor:var(--color-brand)
bg:brandbg-brandbackground-color:var(--color-brand)
p:mdp-mdpadding:var(--spacing-md)
m:-sm-m-smmargin:calc(var(--spacing-sm) * -1)
fg:red/0.5fg-red/0.5color:color-mix(in oklab,var(--color-red) 50%,transparent)
font:16pxfont-size:16pxKeeps the old font-size-only intent.
bg:#fff with color-only intentbackground-color:#fffKeeps other background longhands. New bg:#fff means background:#fff.
b:2px with width-only intentborder-width:2pxKeeps border style and color. New b:2px means border:2px.
outline:2px with width-only intentoutline-width:2pxNative outline:2px resets the other outline longhands.
stroke:2px with width-only intentstroke-width:2pxNative stroke specifies SVG paint, not stroke width.
line-clamp:3 with combined truncation intentclamp-lines:3Retains the legacy multi-property truncation utility. line-clamp:3 emits the native declaration.
p:4x with RC defaultsp:1remConverts the old length multiplier; verify the original settings first.
fg:$color-brandfg:var(--color-brand)Explicit native custom-property reference.
m:sm|mdm:var(--spacing-sm)|var(--spacing-md)Explicit references in a multi-value declaration.
grid-cols:3UnchangedExplicit Master parameter utility.
RC size:20pxwidth:20px height:20pxThe paired sizing family is removed; review cascade order.

The examples above show variable-backed tokens. A token declared with @theme inline substitutes its declared value instead of a var() reference.

CSS keywords keep native meaning. color:red and fg:red mean the CSS color red; color-red and fg-red select the project's color token. font-family:mono specifies a font named mono and does not resolve --font-family-mono.

There is no implicit token lookup inside a colon value, including functions, fallbacks, and multi-value declarations. For example, use border:1px|solid|var(--color-line-base) and transition:opacity|var(--duration-normal)|var(--easing-standard) when those variables exist.

Preserve selectors and conditions

Keep state suffixes, responsive conditions, important markers, grouping, and | space encoding. Change each affected item inside a group independently.

RC reference — not executed
font:mono:hover@sm!{p:md;fg:brand}:hover

For this new example, define the project color token explicitly:

@theme { --color-brand: #4f46e5; }
New v2 syntax
font-mono:hover@sm!{p-md;fg-brand}:hover

Named tokens do not introduce a numeric multiplier scale. p-4 only works if the project defines the corresponding spacing token. Use a real CSS length for a literal.


3. Review resets, names, and cascade order

Native shorthand resets

Choose the property that expresses the original intent. A native shorthand resets omitted longhands, even when its value looks like a single color or width. For example, background:#fff resets background images, positioning, repeat, and sizing; background-color:#fff does not. border:2px also resets border style, whose initial value does not draw a border.

font:16px is not a valid standalone native font shorthand. Use font-size:16px when changing only the size. Use a complete native font value only when its shorthand behavior is intended.

Validate the resulting CSS in a browser. A syntax match is distinct from CSS value validity and from visual equivalence.

Reserved names and ambiguity

Static and enum names keep their existing meanings. bg-cover still emits background-size:cover, even if --color-cover exists; use background-color-cover for that token.

Use full prefixes to resolve collisions. If both --font-family-brand and --font-size-brand exist, font-brand is ambiguous. Choose font-family-brand or font-size-brand. Different utilities cannot resolve ambiguity through registration order.

Resolution uses the longest registered prefix. A missing font-family-sm does not fall back to font-sm. Hyphens inside token names remain part of the token: p-card-body selects --spacing-card-body.

A single utility's explicit namespace fallback order remains meaningful. Negative names apply only to numeric tokens on properties that accept negative values; opacity suffixes apply only to color tokens and use the range 0..1.

Direct values override tokens within the same scope

Both p-md p:8px and p:8px p-md put the token rule before the direct-value rule, so the direct padding wins. HTML class order does not control this result.

Layers, conditions, selector priority, shorthand/longhand tiers, and CSS importance still matter. A padding longhand can override a padding shorthand; an important token can override a normal direct value. Review combinations that relied on RC ordering instead of assuming that every renamed class preserves the previous winner.


4. Replace length x, base-unit, and $name

Master's custom length multiplier is removed. Convert each old length using the original project's effective settings:

rem value = old x value × old base-unit ÷ old root-size
Original settingsRC lengthEquivalent CSS length
base-unit:4, root-size:164x1rem
base-unit:6, root-size:204x1.2rem
base-unit:6, root-size:20-2.5x-0.75rem

After converting all affected lengths, remove base-unit from CSS settings and baseUnit from manifest inputs. They are rejected by the new compiler and engine. root-size and rootSize are also removed in the final contract. Keep their saved original values for migration only; query conversion must preserve the old generated result.

Preserve native resolution units. CSS uses x as a resolution unit in image-set() and resolution queries. This is valid new syntax and must retain 1x and 2x:

New v2 class
background-image:image-set(url(a.png)|1x,url(b.png)|2x)
Generated declaration
background-image: image-set(url(a.png) 1x, url(b.png) 2x);

Do not globally replace every numeric x: URLs, strings, resolution descriptors, and custom-property token streams need contextual handling. Inspect arithmetic and nested function values. If the migration tool cannot establish whether a dimension represents a length or resolution, review it manually.

Replace a registered $name reference with var(--name). Preserve any original alpha modifier with an explicit color expression or a named color token. Quoted text containing a dollar sign remains text.

These changes reduce special language rules. They are not a claim that AI generation accuracy has improved; that requires separate model evaluation.


5. Update directives, manifests, and custom hosts

Separate token and raw parameter sources in managed patterns:

New v2 utilities
@utilities {  font-<~font-family> {    font-family: --value();  }  size-<~container> {    width: --value();    height: --value();  }  size:<*> {    width: --value();    height: --value();  }}

prefix-<~namespace> accepts token sources only. Use key:<*> for a complete raw CSS value and a hyphen enum for named options. The former =namespace, typed raw and colon enum forms are historical RC syntax; migrate them through the utility stage below. Full-value --value() substitution remains supported.

A managed definition using a native property name must preserve that property's intent and value. Matching vendor-prefixed declarations may accompany it; changing to a subproperty or adding a separate style effect requires a distinct utility name. For example, migrate the old combined line-clamp definition to clamp-lines.

Regenerate artifacts from their source definitions. Manifest and hydration envelopes remain v1, but the supported field contract changes:

  • Token matchers use { "type": "token", "prefix": "font-" } with namespace references on their utility; the old variable matcher is rejected.
  • Directive IR has a token pattern distinct from dynamic raw parameters.
  • Add languageVersion: 3 to regenerated manifest and hydration data; missing or unsupported language versions are rejected even though their envelope remains version: 1.
  • Replace global mode settings with ordered modes activation definitions, and remove rootSize, defaultMode, modeTrigger, and settings.modes.
  • Remove baseUnit; update consumers of the generated named-token registry to builtinTokenNamespaces.
  • Preserve rule source priority and semantic sort keys across composition, server rendering, and hydration.
  • Update native and Wasm providers together to binding ABI 13. Custom engine adapters must still implement the complete engine interface, including executionState().
  • Rebuild cached generated CSS, server output, progressive payloads, and hydration artifacts with the same package set. Do not mix old rule data with a new runtime.

See the directives contract and rendering modes for the current interfaces. Legacy parsing belongs to the explicitly invoked migration workflow; the production runtime has no old-token fallback.


6. Preview and apply migration proposals

Save the resolved original manifest as master.rc.manifest.json before upgrading. Run the migration command from the project root; --manifest selects that saved file. Missing, unreadable, or invalid configuration stops migration before any writes:

master-css migrate src app.css --from rc-legacy --source-version YOUR_ACTUAL_RC_VERSION --manifest master.rc.manifest.json

The default operation proposes changes without writing source files. Inspect the proposal and its diagnostics before applying safe edits:

master-css migrate src app.css --from rc-legacy --source-version YOUR_ACTUAL_RC_VERSION --manifest master.rc.manifest.json --write

Automatic changes must preserve the token identity, declaration intent, state, and conditions. Length conversion uses the RC settings rather than the new defaults. Equal current numbers do not justify replacing literals with tokens or converting unrelated px values to rem. Remove the retired canonical lint options preferThemeTokens, preferVariableReferences, and preferMultiValueTokens; token migration now uses this explicit command.

Review these cases manually:

  • Dynamically concatenated class fragments, including prefixes and values assembled at runtime.
  • Names that match multiple token utilities, or custom utility behavior whose equivalence cannot be proven.
  • Class combinations whose winner changes under the new ordering.
  • CSS selectors, querySelector, test locators, and generated selector strings that reference escaped old names.
  • Missing or unreadable RC configuration, unknown source versions, and dimensions with uncertain context.

--write does not override these uncertainties. If any selected file has review diagnostics, the entire selected batch remains unwritten because class and selector dependencies can cross file boundaries. Resolve the diagnostics and preview the batch again. Supply --target-manifest path/to/migrated.json when a migrated project manifest is needed to verify custom definitions. Preserve diagnostics in the upgrade review and resolve them before relying on new build output. Run migration again afterward: already migrated source should produce no additional edits.

Update @compose, safelists, blocklists, dependency-provided classes, and generated-source producers as well as ordinary markup. Update a generator's source before regenerating its output.


7. Complete the final semantics stage

This stage applies to both RC profiles. If named tokens were already migrated, preview with the named profile and the actual saved version:

master-css migrate src app.css --from rc-named --source-version YOUR_ACTUAL_RC_VERSION --manifest master.rc.manifest.json

The version can also come from saved manifest packageVersion metadata. Missing or unreadable metadata is an error, not permission to use current preset defaults. The report includes CSS configuration proposals and project-wide review notes. --write never bypasses those notes or file-level manual-review diagnostics. Include the original CSS settings source when applying configuration changes; replace app.css in these commands with that entry. A source-only batch cannot silently skip the mode configuration proposal.

Preserve the old query result

The RC column is historical, non-executable text. With the old rootSize: 16, these examples preserve the old generated dimensions:

Historical RC referenceExplicit language v2 queryPreserved generated condition
width:10px@>=800width:10px@media((width>=50rem))@media (width>=50rem)
display:grid@supports(display:grid)display:grid@supports((display:grid))@supports (display:grid)

New code authored as @media((width>=800px)) retains 800px; it does not mean the same thing as the first migrated query under every user font setting. Breakpoints and container tokens also retain their authored units. If the same token was used both as a converted RC query and a literal CSS value, split or review it rather than changing both meanings automatically.

Use complete media, supports, and container syntax, including native parentheses:

Language v2 queries
grid-cols:2@media((aspect-ratio>=1.5))display:grid@supports((display:grid))grid-cols:2@container(card|(width>=40rem))gap:1rem@container(style(--density:compact))

Unknown names no longer become container names. Numeric and feature shorthand inference is gone. Repeated wrappers preserve order and nesting. Review class combinations whose old priority depended on inferred dimensions or root size. An invalid old condition that becomes effective after correction requires a manual behavior decision, not an equivalence claim.

Replace global mode settings

@theme ocean assigns values; @mode ocean assigns activation. Remove default-mode, mode-trigger, and settings.modes after introducing explicit branches. For manual light/dark switching with system fallback, define both:

@mode light {  @media (prefers-color-scheme: light) {    :root:not([data-theme]) { @slot; }  }  [data-theme="light"] { @slot; }}@mode dark {  @media (prefers-color-scheme: dark) {    :root:not([data-theme]) { @slot; }  }  [data-theme="dark"] { @slot; }}@theme { --color-panel: white; }@theme dark { --color-panel: #111827; }:root { color-scheme: light dark; }[data-theme="light"] { color-scheme: light; }[data-theme="dark"] { color-scheme: dark; }

Base values come from unqualified @theme; copy the old default-mode values there when needed. The engine no longer adds color-scheme. The migration proposal makes old side effects explicit, but overlapping modes, nested themes, and formerly demand-driven resources still require review. Activation guards now cover the root element and descendants without adding utility specificity. For a shadow tree, define a :host(...) branch explicitly. Neither the old class strategy nor the new mode crosses native shadow boundaries automatically.

Mode redefinition replaces the entire activation definition. Token value blocks still merge by token name. Breakpoints, variants, and modes cannot share names across categories. Mode activation rejects pseudo-elements, declarations, containers, layers, and recursive mode references.

Keep native CSS and choose delivery deliberately

All CSS-producing compiler APIs preserve native CSS by default. Passing classes no longer enables pruning. To retain intentional RC pruning, set pruneNativeCSS: true for project-owned sources, or place @prune native; in each source that should opt in. This directive does not propagate through imports; @preserve native; excludes its own file. preserveNativeCSS: false still means explicitly omit native output and is not a pruning option.

Qualified imports cannot contain global definitions. Move @settings, @theme, @mode, custom variants, and managed definitions to unqualified imports or reference inputs. Pure native qualified imports and native @compose retain native conditions. Review imports whose old behavior hoisted definitions.

Official integration defaults are static. Explicitly set the old rendering mode when preserving a runtime, pre-render, or progressive application. A runtime flag contradicting its mode is a configuration error. Static and pre-render must not include runtime engine, Wasm, or runtime manifest assets. Use ordinary CSS variables for dynamic values in a static app. Rebuild Next manifest imports as bundler-managed ESM modules; do not depend on private .next/static/media filenames or manually assembled URLs.

Update diagnostics and custom hosts

Remove output-affecting supportsNativeDeclaration callbacks. Normal generation preserves even known-invalid native values and reports them separately. Check matchStatus, cssSyntaxStatus, cssValueStatus, and browserSupport; the former valid or matched booleans cannot represent these distinctions. Managed declarations are validated too: grid-cols:2.5 may match but its repeat() count is invalid.

Use validation: 'error' in compiler APIs or master-css generate --strict for atomic failure on known-invalid values. Unknown capabilities and var() results remain unverified, rather than being silently removed. Review CSS that was previously suppressed by a host validator and now reaches the browser.

MCP uses project context by default. A missing entry and an entry that fails to compile return distinct structured errors; neither silently selects the preset. Select context: "preset" explicitly for isolated preset queries. Consumers must read result version 3, full diagnostic and dependency arrays, context metadata, manifest fingerprint, language version, and binding version. Update editor, CLI, native, Wasm, server, and hydration consumers together. Ordinary canonical autofix does not perform version migration or infer pixel/rem equivalence.


8. Verify the coordinated upgrade

  • Run the project's build, lint, type-check, and focused application tests with the upgraded package set.
  • Compare generated declarations against the saved RC baseline. Explain every difference, including intentionally restored native shorthand semantics and native resolution units.
  • Test both orders of token/literal combinations, plus longhands, important values, state selectors, responsive conditions, and themes.
  • Check fonts, line heights, letter spacing, backgrounds, borders, outlines, SVG paint and width, and truncation in a browser.
  • Compare static, server, runtime, and progressive results wherever the project uses them. Inspect initial hydration and subsequent DOM class updates.
  • Check resource retention for tokens referenced by explicit var(), functions, compositions, modes, and managed animations.
  • Verify completion, hover, validation, conflict diagnostics, and autofix on representative new classes. Ambiguous names should report explicit alternatives.
  • Confirm that official source paths and executable examples no longer rely on RC token syntax, $name, base-unit, or Master length x.

Keep the saved baseline and manual-review decisions with the upgrade change. Remove obsolete RC artifacts only after all rendering paths and important screens validate.


9. RC-native boundary and deterministic-build migration

Select the profile matching the saved installation, not the version you are installing:

ProfileSaved starting contract
rc-legacyColon tokens, length x, $name, inferred queries and global mode settings
rc-namedNamed tokens and native declaration semantics, before explicit modes and native-query semantics
rc-nativeExplicit @mode, preserved native values and native query suffixes, before the simple-query and source-lifecycle contract
rc-managedBefore native component authoring and ordered utility composition
rc-utilitiesNative components and ordered composition, before fixed raw intent and whole-definition replacement
rc-sizingFour utility definition forms, before entry-level replacement, token ambiguity correction, and removal of built-in paired dimensions

Every profile requires the actual package version and saved resolved manifest. rc-native does not apply the old mode or root-size conversions.

master-css migrate src --from rc-native --source-version YOUR_SAVED_RC_VERSION --manifest master.rc.manifest.jsonmaster-css migrate src --from rc-native --source-version YOUR_SAVED_RC_VERSION --manifest master.rc.manifest.json --entry src/master.css --write

Preview is the default. A batch containing any manual-review item writes nothing. The tool checks source contents again before writing. Use --entry when the project has multiple Master entries; preview still shows the complete proposed CSS.

Keep native values native

The compiler no longer treats --alpha() as a macro. A confirmed old macro call migrates from the following historical RC source:

Historical RC-native macro; display only
color: --alpha(var(--color-brand) / .5);
New native declaration
color: color-mix(in oklab, var(--color-brand) 50%, transparent);

The migration preserves the old oklab space and proportions. A project defining native @function --alpha requires manual review. Ordinary declarations preserve --value() as a native call; only managed patterns substitute it. Native custom-property streams such as --pipe:a|b and --money:$100 keep their spelling. They receive structure checks and an unknown value-grammar status when their type is not known.

Move complex class queries into CSS

Classes retain named conditions, a single media type, one boolean feature/declaration/range, one supports declaration, and a container name with one size or custom-property style query. Functions inside a single value may remain. Repeated simple suffixes retain their wrapper order.

Top-level and, or, not, only, query lists, selector(), compound style queries and literal-pipe syntax belong in CSS. The engine reports MASTER_QUERY_REQUIRES_CSS and includes a CSS template; no quoted-query or new escape syntax is introduced.

New complex condition definition
@custom-variant language-selector {  @supports selector([lang|=en]) {    @slot;  }}
New named condition
<div class="display:block@language-selector"></div>

The migrator proposes names such as migrated-query-<stable-digest> independent of file order. Literal pipes that may have been misdecoded, invalid old queries, generated-selector references, dynamic source and cascade changes require review. Equivalent ranges now share sorting data while retaining original output wrappers; compare overlapping rules against saved CSS and computed styles.

Update source and tool consumers

A source update now replaces its previous class set. Empty content and deletion release rules and resources after their final reference disappears. Custom scanner hosts must use scanSource, removeSource, reconcileSources, registerNativeClasses(owner, names) and removeOwner, and preserve ownership for virtual examples. Candidate collection does not register usage.

Markdown/MDX display text, code fences, inline code and frontmatter no longer generate CSS automatically. Actual JSX/HTML, ESM and expressions still do. Register live examples as parented virtual sources or safelist them. Parsing failures report SOURCE_PARSE_ERROR; they do not fall back to raw text or clear previous successful output.

Use validation: 'report' | 'error' for compiler/stylesheet APIs. The former cssValuePolicy option is rejected. Strict syntax/value errors fail the whole result; unknown capabilities alone do not fail. cssSyntaxStatus, cssValueStatus, matchStatus and browserSupport describe separate checks; an unchecked browser is not-checked.

Upgrade bindings and tools together: ABI 13, source result 2, validator 3, language result 4, diagnostics report 3, MCP result 3. Manifest and hydration envelopes remain v1 with languageVersion: 3; regenerate hydration priorities rather than filling missing fields with RC defaults.

MCP v3 returns { version, metadata, diagnostics, result }. result is either { status: 'success', data } or { status: 'error', error: { code, message } }. Read the published output schema. JSON text equals structuredContent; errors also set isError. Unavailable context/fingerprint data is null and dependencies remain explicit arrays.

Finally verify cold and incremental builds using the same source set: replace, empty, delete and rename a file; change .gitignore; exercise shared classes and live examples; test Next worker publication and custom distDir. Confirm failed builds retain only the last complete development output and fail production. Compare static, SSR, runtime and progressive output, themes, hydration and browser styles before releasing.

Managed defaults and components

Use --from rc-managed for the contract immediately before native component authoring. The existing rc-legacy, rc-named and rc-native profiles include the same final migration stage.

npx @master/css-cli migrate --from rc-managed --source-version <saved-version> --manifest master.rc.manifest.json

Save the resolved manifest with the original installation before upgrading. Preview is the default; --write applies a batch only after every manual-review item is resolved and every input still matches the analyzed source.

Simple @defaults { prose { ... } } becomes @layer defaults { .prose { ... } }, and @components becomes @layer components with escaped class selectors. Inner declarations and nested rules are preserved. Native styles now ship even when unused and use CSS source order within a layer; native pruning remains opt-in.

Review reported locations for patterns, derived class suffixes, composition references, extraction policy and cascade conflicts. Replace @compose button with native declarations, or intentionally extract shared utility behavior into @utilities. Write component states and conditions as native CSS. The tool does not silently move components into the utilities layer. Rerunning a completed migration produces no further edits.

Utility intent and whole-definition replacement

Select --from rc-utilities for the saved contract immediately before this change. All five profiles finish with this utility migration stage. Continue to supply the actual installed version and original resolved manifest:

master-css migrate src --from rc-utilities --source-version YOUR_SAVED_RC_VERSION --manifest master.rc.manifest.jsonmaster-css migrate src --from rc-utilities --source-version YOUR_SAVED_RC_VERSION --manifest master.rc.manifest.json --target-manifest master.target.manifest.json --write

Convert definitions while preserving acceptance and intent

The following is historical RC syntax, for comparison only:

Historical RC-utilities definitions; display only
@utilities {  size:<number|*> { width: --value(); height: --value(); }  font-<=font-family> { font-family: --value(); }}
Current utility definitions
@utilities {  size:<*> { width: --value(); height: --value(); }  font-<~font-family> { font-family: --value(); }}

A unique raw-any pattern can be simplified safely. Typed-only patterns, colon enums and overloads require review because :<*> accepts more values. Previously unmatched or ineffective input can start generating effective CSS. Do not silently turn x:<number> into x:<*> without auditing its uses.

text-stroke: now always sets -webkit-text-stroke, including its reset behavior. Use text-stroke-width:2px or text-stroke-color:red to preserve the corresponding old longhand effect. The migrator compares the original emitted property; it does not infer intent from a variable's current color or length. Old var() color guesses require manual review. Named color tokens retain their partial color effect.

Audit replacement, conflicts and composition

A later utility replaces an entire earlier definition, including nested selectors, conditions and dependencies. Empty definitions clear previous output while keeping the name registered. Adjacent static definitions can be merged automatically only when their full source order can be preserved. Overrides across imports/packages, overlapping enums, raw/fixed name collisions and dynamic classes require review.

Enum identity uses the key set, so changing key order is still replacement. Duplicate keys are errors. Token identity preserves the ordered namespace list; =namespace becomes ~namespace. Exact static names precede enum names, and both precede tokens. Unknown but structurally valid static pseudo-classes no longer fall through to a declaration.

All four definition forms accept fixed-class @compose. Placeholder substitution is limited to parameterized declaration values. Replace parameter-dependent compose targets with declarations. Native strings, comments and same-name functions outside managed templates are unchanged.

Compare saved and new declarations, their order, selectors, conditions, variables and animations. Inspect the source of every effective and replaced definition. Verify removal and reinsertion release obsolete resources and that a second migration produces no edits. A batch with any review item writes nothing; changed inputs invalidate a pending write.

Rebuild and validate the complete installation

Upgrade binding ABI 13 and rebuild manifests/hydration with envelope v1 and languageVersion: 3. Older language data is rejected. Custom manifest consumers must remove kind, value matchers and segment dispatch; raw entries use a fixed key matcher. Validator, language, diagnostics and MCP outer versions stay unchanged from the preceding stage.

The default validation: 'report' keeps generated CSS and reports known math grammar errors, including missing operands, invalid separators and known function arity. var(), custom functions and environment-dependent results remain unknown unless a definite independent error exists. validation: 'error' fails the whole build without publishing partial CSS. Neither mode selects a different utility based on a value.

Run builds, lint, declaration comparisons and browser checks across your rendering modes. Verify themes, conditions, hover/focus, hydration and subsequent DOM updates. Retain manual-review decisions and the saved baseline; matching current token numbers is not proof of migration equivalence.

Sizing and resolution

Choose --from rc-sizing when upgrading from four utility definition forms with the built-in size family still present. All six profiles pass through this final migration stage. Keep the actual source package version and saved original manifest:

master-css migrate src --from rc-sizing --source-version YOUR_SAVED_RC_VERSION --manifest master.rc.manifest.jsonmaster-css migrate src --from rc-sizing --source-version YOUR_SAVED_RC_VERSION --manifest master.rc.manifest.json --target-manifest master.target.manifest.json --write
Historical RC inputCurrent explicit intent
size:20pxwidth:20px height:20px
min-size:20pxmin-width:20px min-height:20px
max-size:20pxmax-width:20px max-height:20px
size-smwidth-sm height-sm, retaining the original token

Removing the utility does not ban its name: unregistered colon inputs follow native declaration fallback. Do not assume old size: classes are inert; browsers may implement native behavior (the current WebKit test build applies size). Replace the old intent explicitly and compare computed styles. Native @page { size: A4; } remains untouched.

The old min and max aliases retire with min-size and max-size. Logical size-x/size-y aliases and native @page size descriptors are unaffected.

The CLI proposes one grouped replacement, for example {width:20px;height:20px}:hover@sm!, to retain each source occurrence and its suffix. A group is not proof of unchanged sorting. Overlapping width/height rules, selector references, dynamic construction and unproven custom definitions require manual review and block the entire write batch. A custom same-name utility retained in the target manifest is not decomposed. Re-running an applied migration is idempotent.

Removed-utility advice excludes explicitly registered ordinary CSS classes. Custom tooling hosts can pass the project result’s read-only nativeClassNames to createToolingSession or createToolingSessionSync; this suppresses that advice without changing engine generation. The CLI, MCP and language server retain project registrations automatically.

Review token names that used to work only because two definitions happened to produce equal CSS: they now diagnose ambiguity. Give conflicting families distinct prefixes; use suggested full names only when those names actually exist. Overlapping static names and raw keys now replace only their own entry, retaining unrelated aliases. Previously shadowed declarations and resources may therefore change; compare saved output before publishing.

Bare flex still means display:flex. flex:1 and flex:hover select the native property; write display:flex:hover for a state. Completion and hover follow this distinction.

Tooling checks static numeric types as well as math grammar. width:calc(1px + 1s) is invalid, while width:calc(1px * 1px / 1px) has a valid length result. Unknown functions, variables and unresolved percentage contexts remain unknown. Generation preserves declarations; validation: 'error' fails atomically for definite errors.

Next Webpack CSS Modules keep generated theme variables on the compiler's root/mode selectors, delivered through global CSS assets. Remove workarounds that relied on variables copied onto every component: ancestor overrides and nested themes now inherit normally. Turbopack's existing CSS Module directive limitations remain; use native variables from global CSS within Modules.

Rebuild native/Wasm bindings (ABI 13), preset manifests and hydration alongside sources. Manifest/hydration envelope v1 and language version 3 remain unchanged; preserve actual rule/resource/CSSOM verification. Validate light/dark and manual modes, ancestor overrides, route order, HMR and all affected dimensions in browsers before release.


© 2026 Aoyue Design LLC.MIT License
Trademark Policy