Skip to main content

sassy

Make gorgeous themes that speak as boldly as you do.

Write themes like a human

Without Sassy — raw VS Code JSON

// What even is this? How do these colours
// relate?
{
"editor.background": "#1e1e1e",
"editor.foreground": "#e6e6e6",
"statusBar.background": "#002e63",
"panel.background": "#1a1a1a",
"sideBar.background": "#252526",
"activityBar.background": "#333333",
"tab.activeBackground": "#1e1e1e",
"tab.inactiveBackground": "#2d2d2d",
"focusBorder": "#007fd4",
"errorForeground": "#f44747"
}
// Mom? Come pick me up??
With Sassy - Structured, re-usable, just like you

# Define your colour palette in one place.
palette:
white: "#e6e6e6"
black: rgb(5, 5, 5)
blue: oklch(0.6929 0.1647 253.96 / 95%)
red: css(tomato)

# Define semantic, reusable variables to use
# throughout your theme.
vars:
accent: $$blue
std:
fg:
base: $$white
bg:
base: $$black
panel: lighten($(std.bg), 15)
panelLighter: lighten($std.bg.panel, 15)
accent: darken($(accent), 70)
outline: fade($(accent), 30)

# Define your theme sanely using variables
# that _mean_ something!
theme:
colors:
editor:
background: $(std.bg.panel)
foreground: $(std.fg.base)
panel:
background: $(std.bg.panelLighter)
statusBar:
background: $(std.bg.accent)
focusBorder: $(std.outline)

Express yourself

$()

Semantic Variables

Name your colours by what they mean, not what they look like. Change one value and watch it cascade through your entire theme.

f()

Colour Functions

Derive shades with lighten(), darken(), fade(), mix(), and more. Powered by Culori for perceptually accurate results.

->

Resolve & Debug

Trace any colour from expression to final hex. See exactly how variables chain, where functions apply, and why a value resolved the way it did.

oklch

Any Colour Space

Hex, RGB, HSL, OKLCH, CSS named colours — use whatever makes sense. Sassy converts everything to hex for VS Code.

lint

Built-in Linting

Catch duplicate scopes, undefined variables, unused definitions, and precedence issues before they become visual bugs.

--w

Watch Mode

Live rebuilds on save. Smart hash-based output skipping. Point --output-dir at your extensions folder and iterate instantly.