CxJS

SCSS Migration Guide

CxJS 26.3.1 migrates all SCSS files from the deprecated @import syntax to modern Sass modules (@use and @forward). This guide covers how to update your project’s styles to work with the new module system.

Why This Change?

Sass has deprecated @import in favor of @use and @forward. The old @import system uses global scope, leading to naming conflicts and unpredictable load order. The new module system provides explicit dependencies, better encapsulation, and access to modern Sass features like sass:color and sass:math.

Package Upgrades Required

All CxJS theme packages have been restructured. Upgrade to the latest versions:

PackageDescription
cxCore framework
cx-theme-aquamarineAquamarine theme
cx-theme-darkDark theme
cx-theme-frostFrost theme
cx-theme-materialMaterial theme
cx-theme-material-darkMaterial Dark theme
cx-theme-packed-darkPacked Dark theme
cx-theme-space-blueSpace Blue theme

Projects Without a Theme

If your project imports CxJS styles directly without a theme:

Before:

@use 'sass:math';

$cx-include-global-rules: true;
@import "~cx/src/variables";

@function cx-divide($a, $b) {
   @return math.div($a, $b);
}

@import "~cx/src/index";

After:

@use "cx/src/variables" as *;
@use "cx/src/index" as *;

Key changes:

  • Replace @import with @use ... as *
  • Remove the ~ prefix (not needed with modern bundlers)
  • Remove the cx-divide compatibility shim (no longer needed)
  • $cx-include-global-rules is now set through the forward chain (see variable overrides below)

Projects Using a Theme

If your project uses one of the CxJS theme packages:

Before:

@use 'sass:math';

$cx-include-global-rules: true;
@import "~cx-theme-frost/src/variables";

@function cx-divide($a, $b) {
   @return math.div($a, $b);
}

@import "~cx-theme-frost/src/index";

After:

@use "cx-theme-frost/src/index";

That’s it. Theme packages now handle all variable and map configuration internally. The cx-divide shim and $cx-include-global-rules are no longer needed — themes set these through the module system.

Projects With Custom Variable Overrides

If your project customizes theme variables, use the @forward...with() pattern.

Before:

$cx-default-color: #333;
$cx-default-border-radius: 8px;
@import "~cx-theme-frost/src/variables";
@import "~cx-theme-frost/src/index";

After (single file):

// variables.scss
@forward "cx-theme-frost/src/variables" with (
   $cx-default-color: #333 !default,
   $cx-default-border-radius: 8px !default
);
// index.scss
@use "./variables" as *;
@use "cx-theme-frost/src/maps" as *;
@use "cx-theme-frost/src/overrides";

The @forward...with() mechanism configures variables at load time. Values marked !default respect earlier overrides, enabling a clean three-layer configuration chain: app → theme → framework.

Custom Themes

If you maintain a custom CxJS theme, restructure it to follow the new module pattern:

my-theme/src/
├── index.scss          # Entry point
├── variables.scss      # @forward cx/src/variables with (overrides)
├── variables.reset.scss # @forward ./variables with ($cx-include-global-rules: true)
├── maps.scss           # @forward cx/src/maps + deep-merge overrides
└── overrides.scss      # CSS overrides (loads cx/src/index)

index.scss — Entry point that loads everything in the correct order:

@use "sass:map";

// 1. Load theme variables (configures cx variables via @forward...with())
@use "./variables.reset" as *;

// 2. Load theme maps (configures cx maps via deep-merge)
@use "./maps" as *;

// 3. Load theme overrides (loads cx/src/index + CSS overrides)
@use "./overrides";

variables.reset.scss — Enables global rules and forwards variables:

@forward "./variables" with ($cx-include-global-rules: true);

variables.scss — Define overrides and forward to the framework:

@use "sass:color";

// Theme-specific variables
$my-primary: #3f51b5 !default;

// Forward framework variables with theme defaults
@forward "cx/src/variables" with (
   $cx-default-color: #333 !default,
   $cx-default-border-radius: 4px !default,
   $cx-default-button-background-color: $my-primary !default
);

maps.scss — Override state style maps:

@forward "cx/src/maps";

@use "./variables" as *;
@use "cx/src/maps" as *;
@use "cx/src/util/scss/deep-merge" as *;

$cx-button-state-style-map: cx-deep-map-merge(
   $cx-button-state-style-map,
   (
      hover: (background-color: color.adjust($my-primary, $lightness: -5%))
   )
);

overrides.scss — Load the framework and add CSS overrides:

@use "./variables" as *;
@use "cx/src/index" as *;

.cxb-button {
   text-transform: uppercase;
}

Deprecated Sass Functions

Replace deprecated color functions with their modern equivalents:

DeprecatedModern
darken($color, 10%)color.adjust($color, $lightness: -10%)
lighten($color, 10%)color.adjust($color, $lightness: 10%)
transparentize($color, 0.5)color.adjust($color, $alpha: -0.5)
$a / $b (division)math.div($a, $b)

Add @use "sass:color"; and @use "sass:math"; at the top of files that use these functions.

CxJS also provides CSS variable-aware alternatives: cx-lighten(), cx-darken(), and cx-calc() from cx/src/util/scss/calc. These support both regular values and CSS custom properties.

SCSS Manifest Must Be the First Import

If you use cx-scss-manifest-webpack-plugin or a hand-written manifest for CSS tree-shaking, the manifest must be the very first @use in your SCSS entry file — before the theme or any other CxJS imports.

@use "manifest";
@use "cx-theme-frost/src/index";

CxJS now registers widget dependencies during variable loading. The manifest must be loaded first so the include system is configured before any dependency registration or style compilation occurs. If the manifest is loaded after the theme, styles will not be correctly tree-shaken.

New Theme: cx-theme-variables

As an alternative to SCSS-based themes, this release introduces cx-theme-variables, a new theme built entirely on CSS custom properties. Unlike SCSS-based themes where colors are baked in at compile time, this theme outputs var(--cx-...) references, enabling runtime theme switching (e.g., light/dark mode) without recompilation. It ships with ready-made presets and tweaks for rounding, density, and fonts. Try it out in the Theme Editor.