vd3 Architecture Guide
vd3 is a single, standalone Vue 3 package. Everything is generated in one direction — design tokens → generated color CSS → absorbed component CSS → typed components & composables — so the styling and the behaviour always agree on the same --vd-* tokens and vd-* classes. There is no separate runtime to boot: the components are the runtime.
Design tokens (DTCG)
The source of truth lives as DTCG-format JSON under tokens/ (primitive scales, semantic colors, customizer metadata). Nothing above this layer hard-codes a hex value.
Generated color CSS
The token build turns that JSON into --vd-* custom-property layers — raw scales plus an active palette with a [data-palette] switch — and a flat tokens.json for design tooling.
Absorbed component CSS
The CSS build inlines the generated token layers together with the core, primitive, component, utility and effect stylesheets into one bundle — the whole design system in a single import.
Vue components & composables
Typed Vd* single-file components and useX composables read those same tokens/classes at runtime. They ship as a tree-shakeable ESM/CJS barrel with .d.ts types.
What you import
Each layer above surfaces as a stable published entry point. A Vue app only ever touches two of them; the rest are there for tooling.
| Entry point | What it is |
|---|---|
@vanduo-oss/vd3 | The typed, tree-shakeable barrel: every Vd* component, every useX composable, the VanduoVue plugin, and shared types. |
@vanduo-oss/vd3/css | The full absorbed stylesheet — tokens, layout, every component, utilities, effects, and the bundled icon font. Import once. |
@vanduo-oss/vd3/css/core | The same stylesheet without the bundled Phosphor icon fonts, for apps that supply their own icons. |
@vanduo-oss/vd3/tokens.json | The flat { "--vd-name": value } token map (Figma-ready), for design tooling and codegen. |
The build chain
The layers are produced by a deterministic, top-to-bottom build. You never run it — you install the prebuilt dist/ — but it shows how one source of tokens becomes CSS and components:
# How the package is built (you consume the prebuilt dist/)
clean-dist # wipe dist/
build-tokens.mjs # DTCG JSON -> generated color CSS + tokens.json
build-css.mjs # inline every layer -> vd3.min.css (+ core, icon-free)
vite build # SFCs -> ESM/CJS barrel
vue-tsc # emit .d.ts types
check-class-coverage.mjs # verify every documented class shipsWiring an app
Consuming it is two imports: the stylesheet once, and the VanduoVue plugin for theme defaults. That is the whole setup.
// main.ts — the entire vd3 wiring, no runtime to bootstrap
import { createApp } from 'vue';
import { VanduoVue } from '@vanduo-oss/vd3';
import '@vanduo-oss/vd3/css'; // absorbed component CSS, one import
import App from './App.vue';
createApp(App).use(VanduoVue).mount('#app');No global runtime
Behaviour is not injected by a global object that scans the DOM. Every interactive piece is a Vue component or composable that wires its own listeners on mount and cleans them up on unmount — reactive, tree-shakeable, and tied to the component lifecycle.
// Behaviour ships as plain Vue — components own their own lifecycle
import { VdModal, VdToast } from '@vanduo-oss/vd3';
import { useToast, useTheme } from '@vanduo-oss/vd3';
// A composable wires listeners on mount and tears them down on unmount;
// there is no global registry and no imperative DOM scan to remember.
const toast = useToast();
toast.success('Saved');There is no standalone script to load and no global object to initialise — the package is pure Vue, so it tree-shakes with your app and cleans up with your components.