Skip to main contentSkip to docs navigation

Installation

Install Chassis CSS and its tokens peer, import them in your stylesheet, and produce a CSS build for your project.

This page covers the project-as-dependency path: install @chassis-ui/css from npm, install the matching @chassis-ui/tokens build, and import them in the right order. If you intend to fork Chassis and own the framework yourself, read Clone and Customize instead.

Prerequisites

  • Node.js 18 or later
  • A package manager: pnpm, npm, or yarn
  • A Sass compiler in your build pipeline (Dart Sass) — Chassis ships as Sass source, not pre-compiled CSS for project use

Install the packages

Chassis CSS is published to npm as @chassis-ui/css. The framework consumes design tokens from a separate package, @chassis-ui/tokens, which you install alongside it. Two optional peer dependencies cover specific component groups — install only what you use, or use chassis.bundle.* which includes both.

Shell
# pnpm
pnpm add @chassis-ui/css @chassis-ui/tokens
pnpm add @floating-ui/dom      # menus, popovers, tooltips
pnpm add vanilla-calendar-pro  # datepicker

# npm
npm install @chassis-ui/css @chassis-ui/tokens
npm install @floating-ui/dom vanilla-calendar-pro

# yarn
yarn add @chassis-ui/css @chassis-ui/tokens
yarn add @floating-ui/dom vanilla-calendar-pro

@chassis-ui/tokens ships pre-built token files in dist/web/{app}/{brand}/. The default docs/chassis build is included so the framework works out of the box; switching to a different token set is a configuration change covered under Customize → Sass.

Import order

Chassis ships on the Sass module system (@use / @forward). In your stylesheet, a single @use directive is all that's needed:

SCSS
// styles.scss
@use "@chassis-ui/css/scss/chassis";

Token resolution happens through your build tool's loadPaths configuration — no separate token import is needed in the stylesheet. See the bundler guides (Vite, Webpack, Parcel) for how loadPaths is set up.

To override settings, configure the defaults module at the @use call site — the with (…) block must precede the chassis import:

SCSS
// styles.scss
@use "@chassis-ui/css/scss/config" with (
  $enable-dark-mode: false,
  $clamp-font-size-scale: .8,
);
@use "@chassis-ui/css/scss/chassis";

Every variable in scss/config/_settings.scss uses !default, so only the values listed in with (…) are overridden — the rest keep their defaults. See Options for the full list.

What the package ships

After install, node_modules/@chassis-ui/css/ contains the pre-built distribution and the source files you'll most often import:

TEXT
@chassis-ui/css/
├── dist/
│   ├── css/
│   │   ├── chassis.css              ← full bundle, compiled with default settings
│   │   ├── chassis.min.css
│   │   ├── chassis-grid.css         ← layout grid only
│   │   ├── chassis-grid.min.css
│   │   ├── chassis-reboot.css       ← CSS reset only
│   │   ├── chassis-reboot.min.css
│   │   ├── chassis-utilities.css    ← utility classes only
│   │   └── chassis-utilities.min.css
│   └── js/
│       ├── chassis.js               ← ESM bundle; peer deps are external
│       ├── chassis.min.js
│       ├── chassis.bundle.js        ← ESM bundle with all peer deps included
│       └── chassis.bundle.min.js
├── js/
│   ├── index.js                     ← ESM entry; re-exports all plugins
│   ├── src/                         ← individual plugin sources
│   └── dist/                        ← individual compiled plugins
└── scss/
    ├── chassis.scss                 ← full bundle entry
    ├── chassis-grid.scss            ← grid-only entry
    ├── chassis-reboot.scss          ← reboot-only entry
    ├── chassis-utilities.scss       ← utilities-only entry
    ├── config/
    │   ├── _settings.scss           ← $enable-* feature flags
    │   └── _vendor.scss             ← forwards chassis-tokens
    ├── mixins/
    ├── placeholders/
    └── _*.scss                      ← per-component partials

The pre-compiled dist/css/chassis.css uses the default docs/chassis token build and default settings. It's useful for prototypes and the Quick Start flow, but for any real project compile from source so your token overrides and $enable-* settings apply.

Compile your CSS

If you don't already have a Sass build, install Dart Sass and compile your stylesheet:

Shell
npm install -D sass
npx sass --watch --load-path node_modules/ scss/styles.scss dist/styles.css

If you're using a bundler, follow the bundler-specific guide:

  • Vite — set up the Sass preprocessor and you're done.
  • Webpack — Sass + PostCSS loaders, CSS extraction.
  • Parcel — Parcel auto-detects Sass; very little configuration needed.

Apply the --cx- prefix

Some Chassis components and JS plugins read CSS custom properties with a --cx- prefix at runtime (--cx-carousel-interval, --cx-breakpoint-*) — Sass only ever writes the unprefixed name (--carousel-interval). A separate PostCSS step adds the prefix; install the plugin and add a config file next to package.json (the .mjs extension keeps it an ES module regardless of package.json's own "type" field, since @chassis-ui/css/postcss is ESM-only):

Shell
npm install -D postcss-cli postcss-prefix-custom-properties
JavaScript
// postcss.config.mjs
import { chassisPrefix } from '@chassis-ui/css/postcss'

export default {
  plugins: [chassisPrefix()]
}
Shell
npx postcss dist/styles.css -o dist/styles.css

Run this after every Sass compile. The bundler guides wire the same plugin into the bundler's own PostCSS step instead of a separate CLI call.

To use a different namespace, pass a prefix:

JavaScript
// postcss.config.mjs
import { chassisPrefix } from '@chassis-ui/css/postcss'

export default {
  plugins: [chassisPrefix({ prefix: 'acme-' })]
}

The prefix must start with a letter and end in - or _. It renames CSS custom properties only: data-cx-* attributes such as data-cx-theme and data-cx-toggle keep their names.

The preset also writes the prefix into a --chassis-prefix property on :root, in every stylesheet it prefixes. The JS plugins read that property at runtime, so the prebuilt Chassis JS works with a renamed namespace without a rebuild.

The preset renames every custom property in the CSS it processes, including your own. If your own stylesheets run through the same PostCSS config, reference their properties with the prefix (var(--cx-my-color)) in HTML and JavaScript.

Without a prefix

The prefix step is optional unless you use the Tailwind entry point. Skip it, or pass chassisPrefix({ prefix: '' }), to keep the plain names Sass writes (--primary, --carousel-interval). No --chassis-prefix property is written, so the JS plugins read the plain names too.

Tailwind builds need a prefix: Chassis's plain --breakpoint-*, --container-*, and --color-* properties share names with Tailwind's own theme keys, so chassisPrefix({ prefix: '', tailwind: true }) throws an error.

Include the JavaScript

Chassis JS is optional — only needed for components with interactive behaviour (dropdowns, modals, accordions, etc.). Two ways to include it depending on your setup:

As an ES module (bundlers, modern apps):

JavaScript
// Everything
import * as chassis from '@chassis-ui/css'

// Or just the plugins you use
import { Modal, Tooltip } from '@chassis-ui/css'

As a module script (no bundler):

HTML
<script type="module" src="node_modules/@chassis-ui/css/dist/js/chassis.bundle.min.js"></script>

Use chassis.bundle.* to get Chassis JS with @floating-ui/dom and vanilla-calendar-pro bundled in. Use the plain chassis.* files if you're loading those peers separately through your bundler.

See JavaScript for data attributes, the programmatic API, events, and the full plugin list.

Verify the build

A minimal HTML page that pulls in your compiled CSS should look like this:

HTML
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Chassis CSS</title>
    <link rel="stylesheet" href="/dist/styles.css">
  </head>
  <body>
    <div class="container py-lg">
      <button class="button primary">It works</button>
    </div>
  </body>
</html>

If the button renders with the primary palette and rounded corners, your tokens, settings, and CSS pipeline are wired correctly.

Next steps