visual-source Svelte Themes

Visual Source

GUI for managing your projects design tokens

Visual Source

Visual Source is an opionated GUI for managing your projects design tokens locally.

It supports definings color palettes, color tokens, spacing tokens and more. Please note this is alpha software! It is a proof-of-concept I have found useful for my own projects, but there is still a lot to be done. Feedback and contributions are welcome.

Screenshot 2025-06-07 at 11 54 16 PM

Why Visual Source?

When getting started with a new project coming up with design tokens, and then updating them as your refine the look can be a slow process. Visual Source tries to solve this by giving you a design token GUI locally in your project. As you make changes, we regenerate CSS and you see the results in your app immediately! It gives you source of truth to document your tokens, and tools to do things quickly which are otherwise tedious in a text editor.

Check it out

A web build of the UI is hosted at jhwz.github.io/visual-source so you can try out the interface and see how the tooling feels before installing anything.

Installation

Download the latest version of Visual Source from the Releases page.

Quick Start

  • Launch the GUI by running visual-source in the root of your project
  • Follow the Getting Started prompt to set up some example tokens
  • Visual Source will start generating CSS files for you to reference. To load in your tokens simply import the generated .visual-source/visual-source.css

When running in the browser, you can also export your tokens in DTCG format via the Download DTCG button — useful for round-tripping into Style Dictionary, Tokens Studio, or any other DTCG-aware pipeline.

Concepts

Visual Source has been built flexibly and aims to accomodate the majority of use cases, but does have some assumptions built in.

Color

Visual Source supports two layers of color tokens: palettes and tokens.

Palettes are variants of a single color (usually shades from light to dark) which can be referenced by other tokens. Tokens directly correspond with the common CSS variables you may have in your app (e.g. --primary-hover or --background). Tokens are able to reference colors in your palettes, so if you make changes to one they are instantly reflected in the other.

Tokens can be organized into groups. A group is a logical set of tokens (e.g. Background, Surface, Primary, Field, Error) and can apply a CSS prefix to its tokens — so a Text 01 token in a group with prefix bg- is emitted as --bg-text-01.

The intended way to organize color tokens with Visual Source is contextual grouping with context classes.

The idea: define one group per UI surface (Background, Surface, Primary, Field, Error, …), give each group the same set of role tokens (Text 01, Text 02, Border, Hover, Disabled, …) named consistently, and turn on the Context flag for each group. Visual Source will then generate an extra class block per group, aliasing the prefixed tokens to unprefixed CSS variables. The first context group (typically Background) also applies to :root, so its tokens are the page-wide defaults.

Components then write context-agnostic CSS:

.card {
  background: var(--bg);
  color: var(--text-01);
  border: 1px solid var(--border);
}
.card .help { color: var(--text-02); }
.card:hover { background: var(--hover); }

…and the surrounding wrapper picks the context — the same .card markup renders correctly on a neutral page, inside a surface, or inside an error region:

<div class="surface"> … card uses surface tokens … </div>
<div class="error">   … card uses error tokens   … </div>

This works because CSS custom properties inherit through the DOM. Each context class redefines the unprefixed variables (--text-01, --border, --hover, …) for its subtree, and components pick up whatever's nearest.

When to deviate. Some tokens shouldn't change with context — focus rings, scrim/overlay, brand-fixed accents, anchor link colors, selection highlight, shadow elevations, radii. Leave the Context flag off on those groups; they'll be emitted as plain CSS variables only and behave globally.

You're not required to use this pattern — non-contextual groups still work fine, and you can mix-and-match. But unless you have a reason to do otherwise, contextual grouping is what the tool is designed around.

Spacing

Spacing support is currently very rudimentary. We allow you to define one scale of spacing tokens to be used, and these tokens are generated directly into the CSS. There is a lot more we could do here still!

General tokens

Anything that isn't a color or a spacing value — border radii, fixed sizes like header-height, transition durations and easings, z-indices, shadows — lives in General Tokens. Each general token is emitted as a single CSS custom property (no -rgb variant, no prefixed groupings).

General tokens can be organised into groups, but those groups are for documentation and organisation only — they do not apply a CSS prefix and do not generate context classes. Theme overrides work the same way as for colour and spacing tokens.

Post-generation hook

If you drop an executable file named generate into .visual-source/, Visual Source will run it every time it regenerates the output files — both during GUI auto-save and when you run visual-source regenerate. The script runs with .visual-source/ as its working directory.

This is useful for any downstream step that should track token changes:

  • copying visual-source.css / visual-source.json into another package
  • running a build, codegen, or formatter over the generated files
  • committing the regenerated outputs
# .visual-source/generate
#!/usr/bin/env bash
set -euo pipefail
cp visual-source.css ../packages/ui/src/tokens.css

Make sure the file is executable (chmod +x .visual-source/generate). A non-zero exit fails visual-source regenerate; in the GUI the error is logged to the developer console and auto-save continues.

On the shoulders of giants

This project wouldn't be possible without the work of the open source projects it's built with.

License

MIT License - see LICENSE file for details.

Top categories

Loading Svelte Themes