v0.16.0 - MIT - dart-sass 1.104.1

Sass, in Rust.

Compile Sass to CSS with no Node, no libsass and no subprocess. A library, a command-line binary, and a WebAssembly module that compiles a whole design system in a browser tab.

$ cargo add accent-sass

main.rs
use accent_sass::{Options, from_string};

let css = from_string(
    "$gap: 1rem;\na { padding: $gap * 2; }".to_owned(),
    &Options::default(),
)?;

assert_eq!(css, "a {\n  padding: 2rem;\n}\n");

// No Node, no libsass, no subprocess. The same
// compiler runs in a browser:
//   import { compileString } from "@zoosky/accent-sass";

The pipeline

Source in, CSS out, checked against the reference

The first three stages are what any Sass compiler does. The fourth is why this one can claim parity rather than resemblance: every build compiles four real frameworks with both engines and fails on a single differing colour value.

  1. parse

    Source text to an AST, in SCSS, the indented syntax, or plain CSS. The syntax follows the file extension unless you override it.

  2. evaluate

    Modules, mixins, functions and colour maths. `@use` and `@forward` resolve through a filesystem you can replace.

  3. serialize

    Expanded or compressed CSS, with `@charset` handling that matches the reference implementation.

  4. verify

    Bulma, Pico, Foundation and USWDS compiled with both engines on every commit. A differing colour value fails the build.

Conformance

The reference implementation is the test

dart-sass 1.104.1 is the reference, and a deviation from it is a bug rather than a dialect. The numbers below come from the official spec suite and from the framework corpus CI compiles on every commit.

14,147 sass-spec tests passing of 14,266
0 lines differing across four frameworks
32,781 lines of USWDS CSS, identical to dart-sass
0.62 MB of WebAssembly, gzipped

What you get

What the compiler actually promises

A short list, because each item is something the code is arranged around rather than something it happens to do.

Parity is the contract

dart-sass is the reference implementation, currently 1.104.1. Where output deliberately differs, the reason is written next to the test. A re-baselined expectation that nobody checked against the reference is how wrong behaviour gets frozen, so it is not allowed.

Real frameworks, every commit

Bulma, Pico, Foundation and USWDS compile with both engines in CI, and any differing colour value fails the job. All four compile byte-identically to dart-sass; for USWDS that is 32,781 lines on both sides, comments included.

The filesystem is a seam

Options::fs takes any Fs implementation, so a host that already holds its stylesheets never writes them to disk. MemoryFs ships as one, and is what the browser build resolves imports through.

It runs in a browser

A WebAssembly build exposes compileString and compile with dart-sass's option names. The demo on this site compiles USWDS -- 605 stylesheets -- client side, with nothing sent anywhere.

Compile Sass at build time

accent_sass::include! compiles a stylesheet into your binary during cargo build, tracked for incremental rebuilds. No asset pipeline, no build script, no runtime cost.

A C ABI for plugin hosts

The wasi-exports feature exposes a C ABI for wasm32-wasip1, so a host can instantiate the compiler once and compile many stylesheets without paying process startup for each.

Why a Rust implementation

dart-sass is the reference implementation and it is written in Dart. A Rust program that wants Sass has three options: shell out to a Node or Dart process, bind to the deprecated libsass, or use a native port. The first adds a runtime to your deployment; the second stopped at a dialect of Sass that has since moved on.

This is the third. It is a fork of connorskees/grass, whose last release was 0.13.4 in August 2024, and it carries the modern Dart Sass features upstream has not released -- the colour spaces, color.channel, the module system corners, the calculation long tail -- so that a Rust program can build Bulma or USWDS without another toolchain in the picture.

Parity with dart-sass is the goal rather than an aspiration to approximate it. Where the two cannot agree, the difference is written down rather than emulated silently; Compatibility is the list.

Watch it compile a design system, live

The demo holds Bulma and USWDS in memory and compiles them in your browser. Change a theme token and the whole framework rebuilds from source -- not a layer of CSS pasted on top.