bridgetown-sasso
Compile Sass/SCSS in Bridgetown with sasso — a pure-Rust, zero-dependency, byte-for-byte dart-sass alternative.
Compilation runs in-process during the build — no Node toolchain, no Dart
VM, no subprocess. Bridgetown's default frontend has no native Sass step; this
plugin gives you one without pulling in node + esbuild + the sass npm.
- No Node. Compile Sass with zero JavaScript tooling.
- In-process. No process spawn per build — sasso is a native Ruby gem.
- Byte-for-byte dart-sass. Same CSS as
dart-sass, just faster.
Installation
# Gemfile
gem "bridgetown-sasso"
bundle install
Then enable it in config/initializers.rb:
Bridgetown.configure do |config|
init :"bridgetown-sasso"
end
Put your entrypoint (and its partials) under src/_css/ — the leading
underscore keeps Bridgetown from publishing the raw .scss. The default
entrypoint is src/_css/index.scss, compiled to output/css/main.css. Link it
from your layout:
<link rel="stylesheet" href="/css/main.css">
Or scaffold everything in one step:
bin/bridgetown apply https://github.com/momiji-rs/bridgetown-sasso
Configuration
All optional (defaults shown):
init :"bridgetown-sasso" do
# <source under src/<styles_dir>> => <output under the site output dir>
entrypoints({ "index.scss" => "css/main.css" })
# Dir under src/ holding the entrypoints + their partials. Underscore-prefixed
# so Bridgetown does not publish the raw .scss.
styles_dir "_css"
# nil = :compressed in production (BRIDGETOWN_ENV=production), :expanded else.
# Or force :expanded / :compressed.
style nil
# Extra @use/@import dirs. The entrypoint's own directory is always searched
# first, so sibling partials (e.g. _buttons.scss) need no configuration.
load_paths []
end
Multiple entrypoints are supported — list each one:
entrypoints({ "index.scss" => "css/main.css", "admin.scss" => "css/admin.css" })
Performance
sasso compiles the same CSS as dart-sass, byte-for-byte, but much faster — and
without any Node runtime. Benchmarked on an Apple M2 Max, all engines dart-sass
1.101, against the Node frontend's default Sass engine (sass, dart2js):
In-process (how this plugin compiles — inside the Ruby build process):
| workload | bridgetown-sasso | Node sass (dart2js) |
|---|---|---|
| ~360 rules | 1.2 ms | 8.0 ms (6.4× slower) |
| ~3000 rules | 9.9 ms | 71.5 ms (7.2× slower) |
Cold per-build (a one-shot bridgetown build / deploy, including runtime
startup):
| workload | bridgetown-sasso | dart-sass (native) | Node sass (dart2js) |
|---|---|---|---|
| ~360 rules | 3.0 ms | 27.5 ms (9×) | 185 ms (63× slower) |
| ~3000 rules | 10.9 ms | 64.2 ms (6×) | 348 ms (32× slower) |
Output is byte-identical to dart-sass, so this is pure speedup with no behavior
change. (Synthetic workloads exercising variables, nesting, &, unit math,
color functions, and @at-root; ratios are the takeaway, absolute numbers are
machine-specific.)
How it fits the build
The plugin registers a Bridgetown builder that, after each build, compiles every
configured entrypoint with Sasso.compile and writes the CSS into the site
output directory. bin/bridgetown build and bridgetown serve (watch) both
regenerate it. Because the CSS is produced in-process, there is no Node
dependency for Sass at all.
License
MIT, matching the Sass ecosystem. (The core sasso compiler crate is dual
MIT OR Apache-2.0.)