0.2.0 - 2026-06-11
Release Notes
Everything since the initial 0.1.0 crates.io publish. This grew the compiler
from an early vertical slice to 100% of the attempted official sass-spec
suite (13,896 / 13,896, zero failures — 11,405 byte-exact CSS outputs plus
2,491 error specs correctly rejected; the 8 remaining cases are tagged :todo
for dart-sass itself upstream), matching current dart-sass (1.100) byte-for-byte.
The pass is measured against a conformance harness tightened to reproduce the
official sass-spec comparator (normalizeOutput) exactly — collapse newline
runs only, no extra whitespace leniency — so the count holds under the upstream
comparator, not just a looser local one.
Added
- Byte-exact diagnostics — errors,
@error,@warn, and@debugnow
reproduce dart-sass's stderr byte-for-byte: source-span╷│╵snippets with
carets and right-aligned gutters (tab→4 spaces), aligned stack frames
(root stylesheet/name()/@import), a--no-unicodeflag, and the
@importdeprecation warning (with a per-id cap/dedup deprecation registry).
238 of the suite's 3,256 stderr expectations now match byte-for-byte (a
spec/run_spec.py --check-stderrmetric tracks it); the rest (other
deprecations, multi-span layouts) build on this foundation. @use/@forwardmodule system — built-insass:*modules and user
files,withconfiguration, namespacing,@forwardprefix/show/hide,
dash-insensitive member access, forward conflict resolution, and star
(as *) modules.- Indented
.sasssyntax — a full front-end (Options::with_syntax, the
CLI--indentedflag,.sassextension inference), including cross-syntax
@importof partials by file extension. - CSS Color 4 color spaces —
srgb/display-p3/lab/lch/oklab/
oklch/xyzviacolor(), with modern color serialization. @extendand%placeholders — a faithful port of dart-sass's
ExtensionStoreengine: registration-order extension folding, selector
weaving/unification/trimming,@use/@forwardcross-module visibility, and
the self-referential:not/:haspseudo cases — closing the suite's
@extendfamily to byte-exact parity.- Built-in function modules —
meta(first-class function references via
get-function/call, existence predicates),math(clamp/min/max/
round/logand friends),list(bracket-preservingjoin/append),
map(nested key paths,deep-merge/deep-remove),string
(split/unique-id), andselectorfunctions. - First-class mixins —
meta.get-mixinreturns a mixin value and
meta.applyinvokes it (with@contentsupport). - CLI — compile multiple input files in one process (
sasso a.scss b.scss,
startup shared across files);--loop <N>for in-process throughput and
-q/--quietto suppress stdout (used by the benchmark harness). - Benchmark harness — sasso registered as a first-class engine in
bench/;
three-way reportbench/three_way.md(sasso vs
dart-sass vs grass). CODE_OF_CONDUCT.mdadopting the
Sass Community Guidelines, as
the Sass project asks every implementation to do.- This CHANGELOG.
Changed
- Selector resolution now matches dart-sass on combinator normalization,
adjacent-compound separation, and bogus-combinator omission. colorfunctions match dart-sass strictness: channel-unit leniency in
adjust/change, missing/powerless-channel errors, the Microsoftalpha()
filter overload, andadjust-huerejecting non-legacy colors.selectorfunctions coerce string/list arguments and validate arity, and
accept a list of extendees inextend/replace.listbuiltins validate fixed-arity arguments and preserve list shape.- Unquoted string serialization collapses newlines to spaces; custom-property
values are emitted verbatim — both matching dart-sass. - Control-flow blocks use semi-global scoping with a global-write guard.
Performance
Profiling showed the compiler is allocation- and hashing-bound; a series of
hot-path cuts followed, with no behavior change (cumulative ~2× faster on the
large benchmark vs. the original, lifting the lead over grass to ~1.9–2.4× and
over dart-sass to ~16–25×):
- Selector helpers
split_commas/tokenize_complexreturn borrowed&str
slices, andcopy_name/normalize_selectoravoid their intermediate
String/Vec— no per-part/per-token/per-name heap allocation on the hot
selector-resolution path. - The compiler's internal
String-keyed maps (variable scope, function/mixin
tables, module maps) use a small inline FxHash hasher instead of std's
DoS-resistant-but-slow SipHash. (Still zero runtime dependencies.) - A scoped bump-arena allocator (
ScopedAlloc): within eachcompile()a
per-thread arena turns every allocation into a pointer bump and frees them
wholesale (reset) at the end — a further ~1.5×. It is installed as the CLI's
#[global_allocator]; library/wasm embedders can opt in the same way (it
forwards to the system allocator outside a compile, so it's safe to install
unconditionally). This is the library's one auditedunsafemodule —
verified by unit tests, Miri (no UB), AddressSanitizer, and the full sass-spec
suite run through it (zero crashes, byte-identical output); the
rest of the crate isdeny(unsafe_code). Still zero runtime dependencies. - Smaller
Value— theColorvariant's modern-color payload is boxed, so
theValueenum drops from 128 to 64 bytes (a compile-timesize_of
guard prevents regressions). Halves every scope-map slot,Vec<Value>element
and lookup clone, with byte-identical output. - Zero-dependency Ryū float formatter — a from-scratch
d2sshortest-round-
trip formatter on the float-to-string hot path, replacingcore::fmt, with a
differential fuzz test against a reference.
Tooling
- The conformance ratchet pins the sass-spec commit (
spec/SPEC_VERSION.txt)
for reproducibility, with a--latest/--canarydrift-detection mode. - The conformance harness now reproduces the official sass-spec comparator
(sass-spec/lib/test-case/compare.tsnormalizeOutput) exactly, so a "pass"
means byte-identical under the upstream comparator — no extra local leniency.
Install sasso 0.2.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/momiji-rs/sasso/releases/download/v0.2.0/sasso-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/momiji-rs/sasso/releases/download/v0.2.0/sasso-installer.ps1 | iex"Download sasso 0.2.0
| File | Platform | Checksum |
|---|---|---|
| sasso-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| sasso-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| sasso-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| sasso-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| sasso-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
| sasso-aarch64-unknown-linux-musl.tar.xz | ARM64 MUSL Linux | checksum |
| sasso-x86_64-unknown-linux-musl.tar.xz | x64 MUSL Linux | checksum |