npm

Getting started

Use VUI with any framework

The theme is plain CSS with no JavaScript in it, so it works anywhere that renders HTML. Install @viliha/vui-theme and you have the tokens, dark mode, the z-scale and the motion utilities in Vue, Svelte, Angular, Solid, Astro, Qwik, Lit, Alpine or a hand-written page.

How do I add VUI to a non-React project?

Install the theme package and import it after Tailwind. That is the whole setup, and it is the same file that styles VUI itself.

npm install @viliha/vui-ui
npm install -D tailwindcss @tailwindcss/postcss

/* app/globals.css — the React package carries the theme */
@import "tailwindcss";
@import "@viliha/vui-ui/theme.css";

Now the utility classes resolve to VUI's values: bg-background, text-muted-foreground, bg-popover, rounded-lg. Add .dark to any ancestor for dark mode.

What do I get, and what do I still build?

Be clear-eyed about this. The theme is the design system: the colors, the radius, the type scale, the elevation, the motion. The components are React today. Everywhere else you write the markup and the classes do the styling.

LevelWhat shipsWhere
Theme@viliha/vui-theme: tokens, dark mode, z-scale, motion, scrollbars. No JavaScript, no dependencies.Every framework on this page, today.
Core@viliha/vui-core: the logic without the framework. Runtime theming, table import and export, class merging. Plain TypeScript, no UI framework.Every framework, and Node.
ComponentsA real component package: buttons, inputs, dialogs, menus, tables, the whole set.React and Next.js. Vue has the mechanical components and charts.
Starter kitA scaffolded app: shell, sidebar, open tabs, command palette, demo pages, via npx @viliha/vui-ui init.React and Next.js.

What about the logic, not just the look?

Some of what a design system does is not markup at all: turning a theme into CSS variables, exporting a table to CSV, merging class names without conflicts. That part ships as @viliha/vui-core, plain TypeScript with no UI framework in it.

theming and exporting, in any framework
npm install @viliha/vui-core

import { mergeThemes, applyTheme, rowsToCSV, downloadFile } from "@viliha/vui-core";

// An organization's theme with one person's overrides on top.
applyTheme(document.documentElement, mergeThemes(orgTheme, userTheme));

// Export the rows on screen, no spreadsheet library required.
downloadFile("people.csv", rowsToCSV(columns, rows), "text/csv");

It is generated from the same files the React components use, so the two cannot drift, and the build refuses to publish a module that has picked up a framework import.

Which frameworks are tested?

It is a stylesheet, so it works in anything that renders HTML. These are the ones we have actually wired up:

  • Vue and Nuxt. Tailwind v4 via the Vite plugin; import the theme in your global stylesheet.
  • Svelte and SvelteKit. Same wiring as Vue; add the theme import to app.css.
  • Angular. Tailwind v4 through PostCSS; import the theme in styles.css.
  • Solid. Vite plugin, then the theme import.
  • Astro. Works with or without a React island. Astro components use the classes directly.
  • Qwik. Vite plugin, then the theme import.
  • Lit. Tokens cross the shadow boundary; utility classes do not. Render light DOM to use them.
  • Alpine, HTMX, 11ty, plain HTML. No build step needed. Link the compiled stylesheet, then paste markup from the HTML page.
  • Laravel and Blade. Vite and Tailwind are already there. Import the theme, then build Blade components from the shared class strings.
  • Rails, Django, Go templates, PHP. Same as Laravel without the Blade recipes: import the theme and use the markup.

Frameworks we do not support

We have no plans for Backbone, Knockout, Polymer, Dojo, Mithril, Hyperapp, Ember, Meteor, Marko or Inferno. The CSS will still work in them, because CSS does not care. We just will not answer issues as though we tested it.

Two things to know outside React

Icons

VUI draws every icon as a small bordered chip. In React that keys off Radix icons, which render width="15". Anywhere else, add .vui-icon to the icon and you get the same treatment.

any icon set
<svg class="vui-icon size-4" viewBox="0 0 15 15">…</svg>

Accordion animation

The open and close animation needs the measured content height. Set --vui-accordion-height from whatever your headless library publishes, and the keyframes do the rest.

mapping your library
<!-- Vue (Reka UI) -->
<AccordionContent style="--vui-accordion-height: var(--reka-accordion-content-height)" />

<!-- Svelte (Bits UI) -->
<Accordion.Content style="--vui-accordion-height: var(--bits-accordion-content-height)" />

Where are the Vue and Svelte components?

Not built yet, and we would rather say so than list logos we cannot back. The theme is the part that ports for free, so it ships first. Real component packages are a few months of work each and only worth starting once people are actually using the theme in that framework. If that is you, open an issue and say which framework. That is what decides the order.