Skip to content

CSS

Vantris ships a full CSS pipeline powered by lightningcss: url() rewriting, @import inlining, CSS Modules, Sass/Less, PostCSS, and CSS code splitting — with identical behaviour in dev and build. In dev, CSS hot-swaps with no reload.

Importing CSS

Import a stylesheet from JavaScript and it's injected into the page:

ts
import "./styles/app.css";
  • In dev, the import becomes a style-injecting module — editing the file swaps the <style> in place, no reload, no lost state.
  • In the build, it's processed and emitted as a hashed .css with a <link> injected into the HTML.

You can also link a stylesheet directly in index.html; it's served as text/css in dev and hashed/rewritten in the build if it points into rootDir.

url() and @import

The pipeline handles the two things that break naïve CSS bundling:

  • url() rewritingbackground: url("./bg.png") resolves and hashes the asset, respecting base.
  • @import inlining@import "./base.css" is inlined into the output so the browser doesn't make extra round-trips.

Aliases work inside CSS too:

css
@import "@/styles/base.css";
background: url("@/images/hero.png");

See Aliases.

CSS Modules

Any file ending in *.module.css is treated as a CSS Module — class names are locally scoped and exposed as a JS object:

css
/* Button.module.css */
.primary {
  color: white;
  background: #8b5cf6;
}
tsx
import styles from "./Button.module.css";

export function Button() {
  return <button className={styles.primary}>Click</button>;
}

The imported object maps your local names to the generated, collision-free class names. This works in dev and build.

Sass & Less

Sass and Less are supported when installed — they're optional peer dependencies, so add the one you use:

bash
npm install -D sass
bash
npm install -D less

Then import .scss, .sass, or .less files (including *.module.scss for scoped modules):

ts
import "./styles/app.scss";
import styles from "./Card.module.scss";

Everything else in the pipeline (url(), @import, code splitting) applies to the compiled output.

PostCSS

If a postcss.config.* file exists at the project root, Vantris runs your CSS through PostCSS automatically — no config field needed. Add your plugins there:

js
// postcss.config.js
export default {
  plugins: {
    autoprefixer: {},
  },
};

Install the PostCSS plugins you reference as dev dependencies.

CSS code splitting

Stylesheets imported by lazily-loaded (dynamic-import) chunks are split into their own .css files and loaded alongside their chunk — so a route's CSS ships only when that route loads, in the build. This is automatic.

Hot Module Replacement for CSS

CSS HMR is automatic and needs no opt-in. Editing any stylesheet — plain, CSS Modules, Sass, or Less — updates the <style> in place with no reload and no lost state. See HMR.

The base path

All emitted CSS URLs — url(), @imported assets, injected <link>s — respect base, so a build deployed under a sub-path or a CDN resolves its assets correctly. See Building → base.

Summary

FeatureDevBuildNotes
Plain CSS importStyle-injecting in dev, hashed in build.
url() rewritingHashed, base-aware.
@import inlining
CSS Modules*.module.css / .scss.
Sass / LessOptional peer dep.
PostCSSAuto when postcss.config.* exists.
CSS code splittingPer lazy chunk.
Hot-swap (HMR)No reload, no opt-in.

Released under the MIT License.