true (verb): To make even, accurate, or precise. "True the wheels of a bicycle. True up the sides of a door. True your Sass code before you deploy."
True is a unit-testing tool for Sass code.
- Write tests in plain Sass
- Compile with Dart Sass
- Optional JavaScript test runner integration (e.g. Mocha, Jest, or Vitest)
npm install --save-dev sass-trueTrue requires Dart Sass v1.45.0 or higher:
npm install --save-dev sass-embedded # or `sass`With Node.js package importer:
@use 'pkg:sass-true' as *;With JavaScript test runner:
@use 'true' as *;Without package importer:
// Path may vary based on your project structure
@use '../node_modules/sass-true' as *;True has one configuration variable: $terminal-output (boolean, defaults
to true)
| Value | Behavior |
|---|---|
true (default) |
Shows detailed terminal output for debugging and results. Best for standalone Sass compilation. |
false |
Disables Sass terminal output. Use with JavaScript test runners (they handle their own reporting). |
If you're still using @import instead of @use, use the legacy import path
with the prefixed variable name:
// Path may vary
@import '../node_modules/sass-true/sass/true';
// Variable is named $true-terminal-outputTrue uses familiar testing syntax inspired by JavaScript test frameworks:
True can compare Sass values during compilation:
@include describe('Zip [function]') {
@include it('Zips multiple lists into a single multi-dimensional list') {
// Assert the expected results
@include assert-equal(zip(a b c, 1 2 3), (a 1, b 2, c 3));
}
}Alternative syntax using test-module and test:
@include test-module('Zip [function]') {
@include test('Zips multiple lists into a single multi-dimensional list') {
// Assert the expected results
@include assert-equal(zip(a b c, 1 2 3), (a 1, b 2, c 3));
}
}CSS output tests require a different assertion structure, with an outer assert
mixin, and a matching pair of output and expect to contain the
output-values:
// Test CSS output from mixins
@include it('Outputs a font size and line height based on keyword') {
@include assert {
@include output {
@include font-size('large');
}
@include expect {
font-size: 2rem;
line-height: 3rem;
}
}
}Note: CSS output is compared after compilation. You can review changes manually with
git diffor use a JavaScript test runner for automated comparison.
Display a test summary in CSS output and/or terminal:
@include report;- Full Documentation – Complete API reference and guides
- CHANGELOG.md – Migration notes for upgrading
Integrate True with your existing JS test runner for enhanced reporting and automated CSS output comparison.
npm install --save-dev sass-true
npm install --save-dev sass-embedded # or `sass` (if not already installed)Create your Sass test file (e.g., test/test.scss) using True's syntax (see
Usage).
Create a JavaScript shim to run your Sass tests (e.g., test/sass.test.js):
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import sassTrue from 'sass-true';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const sassFile = path.join(__dirname, 'test.scss');
sassTrue.runSass({ describe, it }, sassFile);Run Mocha, Jest, Vitest, or your test runner. Sass tests will appear in the terminal output.
By default, vitest --watch and jest --watch don't detect Sass file changes.
Vitest solution: Add Sass files to forceRerunTriggers:
// vitest.config.js
module.exports = defineConfig({
test: {
forceRerunTriggers: ['**/*.scss'],
},
});See Vitest documentation for details.
Jest solution: Add "scss" to moduleFileExtensions:
// jest.config.js
module.exports = {
moduleFileExtensions: ['js', 'json', 'scss'],
};See Jest documentation for details.
sassTrue.runSass(testRunnerConfig, sassPathOrSource, sassOptions);Arguments:
-
testRunnerConfig(object, required)Option Type Required Description describefunction Yes Your test runner's describefunctionitfunction Yes Your test runner's itfunctionsassstring or object No Sass implementation name ( 'sass'or'sass-embedded') or instance. Auto-detected if not provided.sourceType'string'or'path'No Set to 'string'to compile inline Sass source instead of file path (default:'path')contextLinesnumber No Number of CSS context lines to show in parse errors (default: 10) -
sassPathOrSource('string'or'path', required)- File path to Sass test file, or
- Inline Sass source code (if
sourceType: 'string')
-
sassOptions(object, optional)- Standard Sass compile options
(
importers,loadPaths,style, etc.) - Default modifications by True:
loadPaths: True's sass directory is automatically added (allowing@use 'true';)importers: Node.js package importer added ifimportersis not defined and Dart Sass ≥ v1.71 (allowing@use 'pkg:sass-true' as *;)
⚠️ Warning: Must usestyle: 'expanded'(default).style: 'compressed'is not supported.
- Standard Sass compile options
(
Call runSass() multiple times to run separate test files:
sassTrue.runSass({ describe, it }, path.join(__dirname, 'functions.test.scss'));
sassTrue.runSass({ describe, it }, path.join(__dirname, 'mixins.test.scss'));Any test runner with describe/it functions (or equivalents) works with True:
// Example with custom test runner
import { suite, test } from 'my-test-runner';
sassTrue.runSass(
{ describe: suite, it: test },
path.join(__dirname, 'test.scss'),
);If you use custom import syntax (e.g., tilde notation
@use '~accoutrement/sass/tools'), you'll need to provide a
custom importer:
import path from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
import sassTrue from 'sass-true';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const importers = [
{
findFileUrl(url) {
if (!url.startsWith('~')) {
return null;
}
return new URL(
pathToFileURL(path.resolve('node_modules', url.substring(1))),
);
},
},
];
const sassFile = path.join(__dirname, 'test.scss');
sassTrue.runSass({ describe, it }, sassFile, { importers });At OddBird, we love contributing to the languages and tools developers rely on. We're currently working on:
- Polyfills for new Popover & Anchor Positioning functionality
- CSS specifications for functions, mixins, and responsive typography
- Sass testing tools like True
Help us keep this work sustainable! Sponsor logos and avatars are featured on our website.