A foundational design system for quickly styling and building Svelte + Vite microsites. Edit your tokens and components in real time — colors, typography, spacing, per-component aliases — and see the site update as you drag the slider. Save the result as a portable configuration you can carry from project to project.
npm install @motion-proto/live-tokens into your app — install once, style fast. The editor is dev-only; production builds get plain CSS variables and your chosen components, nothing else.
:global(:root) block. Rewire any alias from a per-component picker and see that component update everywhere it's used — live, on your real pages, not in a Storybook sandbox./editor route, dev-only) — the home of real-time token editing. Save themes to disk as JSON, promote one to "production" to bake it into a static tokens.css for the build./components route, dev-only) — the home of real-time component-alias editing. Pick token aliases per component without writing CSS..svelte file in VS Code./api/themes/*, /api/component-configs/*, and /api/presets/* routes that persist your edits to disk as you make them.npm install @motion-proto/live-tokens
// vite.config.ts
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import { themeFileApi } from '@motion-proto/live-tokens/vite-plugin';
export default defineConfig({
plugins: [
svelte(),
themeFileApi({
themesDir: 'themes',
tokensCssPath: 'src/styles/tokens.css',
}),
],
optimizeDeps: {
exclude: ['@motion-proto/live-tokens'],
},
});
The themeFileApi plugin:
themes/ with a default theme on first dev-server start.src/components/*.svelte and seeds component-configs/{comp}/default.json from each component's :global(:root) block./api/* routes the editor uses to save and load themes + per-component configs.__PROJECT_ROOT__ for the overlay's "Page Source" link.main.tsimport './styles/tokens.css';
import {
configureEditor,
initializeTheme,
initCssVarSync,
initRouter,
initColumnsOverlay,
initEditorStore,
} from '@motion-proto/live-tokens';
import App from './App.svelte';
configureEditor({ storagePrefix: 'my-app-' });
async function boot() {
initCssVarSync();
initRouter();
initColumnsOverlay();
initEditorStore();
if (import.meta.env.DEV) {
await initializeTheme();
}
new App({ target: document.getElementById('app')! });
}
boot();
<!-- App.svelte -->
<script lang="ts">
import { LiveEditorOverlay, ColumnsOverlay } from '@motion-proto/live-tokens';
import Editor from '@motion-proto/live-tokens/editor';
import ComponentEditorPage from '@motion-proto/live-tokens/component-editor-page';
import { route } from './router';
</script>
<LiveEditorOverlay
navLinks={[
{ path: '/', label: 'Home', icon: 'fa-home' },
{ path: '/components', label: 'Components', icon: 'fa-puzzle-piece' },
]}
pageSources={{
'/': 'src/pages/Home.svelte',
}}
/>
<ColumnsOverlay />
{#if $route === '/editor'}
<Editor />
{:else if $route === '/components'}
<ComponentEditorPage />
{:else}
<!-- your routes -->
{/if}
<LiveEditorOverlay /> self-gates: it only renders in dev, never inside an iframe, and never on the editor route. No need to wrap in {#if import.meta.env.DEV} guards.
<script lang="ts">
import Button from '@motion-proto/live-tokens/components/Button.svelte';
import Callout from '@motion-proto/live-tokens/components/Callout.svelte';
</script>
<Callout variant="info">Read this.</Callout>
<Button variant="primary">Save</Button>
The components carry their own design-token aliases (declared inside each .svelte file). They'll pick up your tokens.css overrides automatically. Strip out the ones you don't use; nothing is forced.
import '@motion-proto/live-tokens/styles/ui-editor.css';
import '@motion-proto/live-tokens/styles/form-controls.css';
import '@motion-proto/live-tokens/styles/fonts.css';
You'll also need your own src/styles/tokens.css declaring your design tokens as CSS variables on :root. Start from the package's default (node_modules/@motion-proto/live-tokens/src/styles/tokens.css) and overlay your overrides — or let the editor seed themes/default.json on first run and promote it.
If you're starting from scratch, skip the manual wiring and clone the repo as a template — App.svelte, main.ts, the router, and a placeholder Home.svelte saying "put your content here" are all pre-wired.
npx degit motionproto/live-tokens my-app
cd my-app
npm install
npm run dev
Open http://localhost:5173 and replace src/pages/Home.svelte with your content. The rest of the wiring is already done — it's the same code the npm package ships, just with the App-shell scaffolding included.
/editor or /components. Saves write to themes/{name}.json and component-configs/{comp}/{name}.json.src/styles/tokens.css and backed up under src/styles/_backups/.npm run build bundles tokens.css as plain CSS. No editor code, no JSON lookups, no dev surfaces ship to prod.Knowing which files the plugin touches matters when upgrading the package or working in a repo you don't want overwritten.
On npm install or npm update: nothing outside node_modules/. No install hooks. Upgrading versions never touches your themes/, component-configs/, presets/, or any file in src/.
At dev-server startup, the plugin only fills gaps — it never overwrites authored files:
themes/default.json — written only if missing.themes/_active.json and themes/_production.json — written only if missing.component-configs/{comp}/_active.json and _production.json — same: only if missing.component-configs/{comp}/default.json — regenerated from the component's :global(:root) block only when the .svelte source is newer than the existing default. This file is a build artifact of the source; don't hand-edit it.At dev-time editor actions, these files get rewritten by your explicit save/promote:
themes/{name}.json — every save in the editor.src/styles/tokens.css — fully regenerated when you save or promote the production theme. Treat this as a build artifact. Hand-edits get clobbered next time the production theme is saved; promote a theme instead.src/styles/fonts.css — same rule: regenerated from the theme's font sources.component-configs/{comp}/{name}.json — every save of a per-component config.The package publishes to npm as @motion-proto/live-tokens.
package.json.npm pack --dry-run.npm publish. prepublishOnly rebuilds dist-plugin/.git tag vX.Y.Z && git push origin main vX.Y.Z.MIT. Originally extracted from RuneGoblin.