Sassy — Feature Inventory
Authoring Formats
Section titled “Authoring Formats”- YAML Input — Write themes in clean, human-readable YAML
Variable System
Section titled “Variable System”- Palette Layer — Define raw colour values in an isolated, self-contained palette scope
- Vars Layer — Build semantic meaning on top of palette with a dedicated variable layer
- Nested Variables — Define deeply nested variable hierarchies with dot-path addressing
- Three Reference Syntaxes —
$(var),$var,${var}— pick the style that fits the context - Palette Aliases —
$$nameshorthand auto-expands to$(palette.name)for concise palette references - Cross-Layer References — Variables can reference other variables, palette entries, and theme values
- Recursive Resolution — Multi-pass evaluation engine resolves chained variable references automatically
- Circular Dependency Detection — Catches self-referential or looping variable chains before they hang
Colour Functions
Section titled “Colour Functions”- lighten / darken — Perceptually uniform brightness adjustments via OKLCH
- mix — Blend two colours at any ratio with OKLCH interpolation
- alpha — Set exact transparency on any colour
- fade / solidify — Relative opacity adjustments — reduce or increase alpha proportionally
- invert — Flip lightness while preserving hue and saturation
- saturate / desaturate — Adjust chroma intensity in OKLCH space
- mute / pop — Semantic aliases for desaturation and saturation
- tint / shade — Mix toward white or black by a given percentage
- shiftHue — Rotate hue by arbitrary degrees
- complement — 180° hue shift in one call
- grayscale — Strip all chroma for a perceptually accurate greyscale
- contrast — Returns black or white, whichever has better contrast against the input
- css() — Use any CSS named colour (
css(tomato),css(deepskyblue), etc.) - Composable Functions — Nest function calls inside each other:
fade(lighten($(bg), 20), 0.5)
Colour Space Support
Section titled “Colour Space Support”- Hex —
#rgb,#rrggbb,#rrggbbaa— with short-form auto-expansion - RGB / RGBA —
rgb(r, g, b)andrgba(r, g, b, a)constructors - HSL / HSLA —
hsl(h, s, l)andhsla(h, s, l, a)constructors - HSV / HSVA —
hsv(h, s, v)andhsva(h, s, v, a)constructors - OKLCH / OKLCHA — Perceptually uniform colour space for professional palette design
- Any Culori Format — LAB, LCH, HWB, Display P3, Rec. 2020 — if Culori parses it, Sassy compiles it
- Cross-Space Mixing — Freely combine colours from different spaces in the same theme
- Alpha Preservation — Hex alpha channels are tracked and preserved through transformations
Import & Composition
Section titled “Import & Composition”- File Imports — Pull in external YAML files via
config.import - Deep Object Merging — Palette, vars, colors, semanticTokenColors merge by deep key override
- Append-Only tokenColors — Imported tokenColors prepend, your file’s rules append — correct precedence by default
- Multi-File Import Chains — Import as many files as needed, merged in declaration order
- Modular Theme Architecture — Split palettes, variables, UI colours, syntax rules, and semantics into separate files
- Shared Palettes — One palette file, many theme variants
- Dynamic Import Paths — Use variables in import paths:
./import/palette-$(type).yaml
Séance Operator
Section titled “Séance Operator”- Prior Value References —
^references the same key’s value from a previously imported file - Derived Variants — Create “hushed”, “vivid”, or any theme variant by transforming inherited values:
shade(^, 25) - Multi-Layer Séance — Chain through multiple import layers with automatic versioned tracking
Theme Sections
Section titled “Theme Sections”- colors — Full support for VS Code workbench colour properties
- tokenColors — TextMate-style syntax highlighting rules with scope selectors
- semanticTokenColors — Semantic token colour definitions for language-aware highlighting
- config.custom — Pass-through block for arbitrary VS Code properties like
semanticHighlighting: true - config.$schema — Embed the VS Code colour theme schema reference in output
CLI — Build Command
Section titled “CLI — Build Command”- Single or Multi-File Builds — Compile one or many theme files in a single invocation
- Watch Mode — Live recompilation on file save with automatic dependency tracking
- Dependency-Aware Watching — Edits to any imported file trigger a rebuild of the parent theme
- Custom Output Directory — Route compiled output wherever you want with
--output-dir - Dry Run — Print compiled JSON to stdout without writing any files
- Silent Mode — Suppress all output except errors — ideal for scripts and CI
- Nerd Mode — Verbose error traces with full stack context for debugging
- Interactive Watch Controls —
F5to force rebuild,Ctrl-Cto quit — with a live prompt - Hash-Based Skip — SHA-256 output comparison prevents unnecessary file writes
- Graceful Signal Handling — Clean shutdown on SIGINT, SIGTERM, SIGHUP
CLI — Resolve Command
Section titled “CLI — Resolve Command”- Color Resolution — Trace any
colors.*property through its full variable chain - tokenColor Resolution — Resolve any TextMate scope to its final foreground value
- semanticTokenColor Resolution — Resolve any semantic token scope to its final value
- Full Resolution Trail — See every substitution step from raw expression to final hex
- Scope Disambiguation — When a scope appears in multiple rules, lists all matches with selectable qualifiers
- Precedence-Aware Resolution — Shows when a broader scope masks your specific one
- Colour Swatches — Truecolour terminal swatches next to resolved hex values
- Alpha Compositing Preview —
--bgflag composites transparent colours against a background for preview
CLI — Proof Command
Section titled “CLI — Proof Command”- Composed Document View — See the fully merged theme document after all imports, overrides, and séance are applied — before any evaluation
- Séance Inlining —
^operators replaced with the actual prior values so the output reads naturally:shade(#4b8ebd, 25) - YAML Output — Outputs in the authoring language, not the compiled format — stays in your world
- Import-Free Output — Imports are resolved and merged; the
importkey is gone — what you see is what the engine sees - Aerial Debugging — Orient yourself in a layered theme before reaching for
resolve— the map before the dig
CLI — Lint Command
Section titled “CLI — Lint Command”- Duplicate Scope Detection — Finds TextMate scopes that appear in multiple tokenColors rules
- Undefined Variable Detection — Catches references to variables that don’t exist
- Unused Variable Detection — Identifies vars defined but never referenced in theme content
- Scope Precedence Analysis — Warns when a broad scope masks a more specific one due to rule ordering
- Token Colour Settings Validation — Validates settings objects: hex colours, fontStyle keywords, unknown properties
- Missing/Empty Settings Detection — Catches tokenColors entries with no settings or empty settings objects
- Deprecated Background Detection — Flags the deprecated
backgroundproperty in tokenColors settings - Multiple Global Default Detection — Warns when multiple scopeless tokenColors entries exist (only the last takes effect)
- Unknown Settings Property Detection — Flags unrecognised properties in tokenColors settings objects
- Semantic Selector Validation — Validates semanticTokenColors selectors against VS Code’s parser rules
- Semantic Token Type Registry — Checks token types and modifiers against VS Code’s 23 standard types and 10 standard modifiers
- Semantic Value Validation — Validates hex colours, fontStyle keywords, and catches the fontStyle-vs-boolean override trap
- Semantic Coherence Checks — Warns when semanticTokenColors rules exist but semanticHighlighting is not enabled
- Duplicate Selector Detection — Finds semanticTokenColors selectors that are identical after modifier normalisation
- Shadowed Rule Detection — Identifies semantic rules overshadowed by higher-specificity rules with the same properties
- Deprecated Usage Warnings — Flags the deprecated
membertoken type and non-functionalbackgroundproperty - Cross-Section Linting — Validates variables in colors, tokenColors, and semanticTokenColors
- Strict Mode —
--stricttreats warnings as errors for CI enforcement - Severity Levels — Issues categorised as high/medium/low with colour-coded terminal output
- Source Location Reporting — Every lint issue includes file, line, and column — even across imported files
- Unnamed Rule Labels — Unnamed tokenColors entries display as
(unnamed rule #N)for easy identification - Import-Aware Analysis — Lints across all imported files, not just the main theme
- Modular Rule Architecture — Lint rules organised in dedicated modules for maintainability
Output
Section titled “Output”- VS Code
.color-theme.json— Standard output format, ready for use in VS Code extensions - Deterministic Output — Same input always produces the same output
- Pretty-Printed JSON — 2-space indented, human-readable output
- Automatic File Naming —
my-theme.yaml→my-theme.color-theme.json
Architecture & Performance
Section titled “Architecture & Performance”- Compose-Then-Evaluate Pipeline — Shared composition step (import → merge → séance) feeds both
compileandproof— one source of truth, two consumers - Phase-Based Compilation — Compose → decompose → evaluate → resolve → assemble — clean, predictable pipeline
- File Caching — Imported files are cached and reused across themes in the same session
- Colour Caching — Parsed colours and mix results are memoised for repeat calls
- OKLCH-Native Operations — Lighten, darken, mix, and saturate all work in perceptually uniform space
- Structured Error Reporting — Chained error contexts with
.trace()for precise failure diagnostics - Max-Iteration Guards — Bounded resolution passes prevent runaway compilation
Programmatic API
Section titled “Programmatic API”- ES Module Exports —
import {Theme, Lint, Resolve, Proof, Colour} from '@gesslar/sassy' - Builder Pattern —
new Theme().setCwd(cwd).setThemeFile(file).setOptions(opts)— no CLI dependencies required - Engine Classes —
Lint,Resolve, andProofwork standalone — give them a Theme, get structured data back - Cache-Optional Loading —
load()falls back toFileObject.loadData()when no cache is set - Embeddable Compilation — Build themes programmatically without the CLI
- Lint Engine —
new Lint().run(theme)— returns categorised issues with severity levels - Resolve Engine —
new Resolve().color(theme, key)— trace any token through its resolution chain - Proof Engine —
new Proof().run(theme)— composed document view before evaluation - YamlSource Export —
YamlSourceclass available for source location tracking in custom tooling - Source Location Lookup —
Theme.findSourceLocation(path)maps compiled output paths back to source file positions - Lint Issue Locations — Lint issue objects include a
locationproperty with file, line, and column - Full Class Access — Theme, Colour, and all engine classes are importable
Developer Experience
Section titled “Developer Experience”- Zero-Install Usage —
npx @gesslar/sassy build— no global install required - TypeScript Definitions — Auto-generated
.d.tsfiles from JSDoc for editor support - Docusaurus Documentation Site — Full docs at sassy.gesslar.io
- Example Themes — Simple and advanced examples included in the repository

