Installation
@viliha/vui-ui ships as TypeScript source, so your bundler compiles it alongside your own code. Install the package, add Tailwind v4, import the theme, and you're ready.
How do I install @viliha/vui-ui?
npm install @viliha/vui-ui
npm install -D tailwindcss @tailwindcss/postcssreact and react-domare peer dependencies, so your app's versions are used (React 18 or 19).
Not using React?
@viliha/vui-theme, with no dependencies. It works in Vue, Svelte, Angular, Solid, Astro, Qwik, Lit, Alpine, HTMX or hand-written HTML. See Use VUI with any framework.Scaffold the whole app + demo (init)
The steps below wire up the theme and components. To also get the app shell (layout, sidebar, open tabs, command palette, nav config, logo) and the demo pages, run the scaffolder in your project. It copies everything into your repo (yours to own and edit) and installs the dependencies:
npx @viliha/vui-ui initFor a brand-new app, start from create-next-app (no srcdir), then run init. It scaffolds the project and auto-installs the dependencies with your package manager. Pick your tool:
npx create-next-app@latest my-app --ts --tailwind --app --no-src-dir --use-npm
cd my-app && npx @viliha/vui-ui init && npm run devThe prompts form a short decision tree: (0) standalone Next.js or a Turborepo (which scaffolds into a target app dir like apps/web), (1) fresh or existing, and (2) pre-built (shell plus demo pages) or theme-only (just the wiring, so you build your own pages).
For CI or agents, a flag maps to each choice:
--nextjs | --turbo standalone app, or a Turborepo (Q0)
--dir <path> Turborepo target app dir (default apps/web)
--fresh | --existing project type (Q1)
--prebuilt | --theme-only pre-built shell + demo, or just the theme (Q2)
--yes, -y accept the defaults with no prompts
--force overwrite existing files
--dry-run preview without writingFresh projects: skip --src-dir
app/ with @/* → ./* and writes a TypeScript next.config.ts. Create the app without --src-dir so there aren't two app/ dirs or two config files. init auto-installs the dependencies with the package manager it detects from your lockfile (npm / pnpm / yarn / bun). Pass --yes to skip the prompt or --no-install to do it yourself.⚠️ Installing into an existing project? Read this
--existing; it never overwrites your next.config, globals.css, or root layout. Pre-built adds the shell/pages under app/(app)/ and app/_components/ and prints the four things to merge yourself (transpilePackages, the theme.css import, the @/* alias, and import "./globals.css"). Preview first with npx @viliha/vui-ui init --existing --prebuilt --dry-run to see exactly what lands. Only want the components? --theme-only copies nothing and just prints the wiring, or skip init entirely (Setup section 3 below). Never run --fresh in an existing project:it overwrites your config with the demo's.1 · New Next.js app
a. Import the theme
In your global stylesheet (e.g. app/globals.css):
@import "tailwindcss";
/* Design tokens, @theme mapping, base reset, and scanning of the
library's component classes, all in one import. */
@import "@viliha/vui-ui/theme.css";b. Transpile the source package
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
transpilePackages: ["@viliha/vui-ui"],
// Pin the workspace root to this app so Next doesn't infer it from a
// stray lockfile higher up the tree (a home-dir bun.lock, an outer monorepo).
turbopack: { root: __dirname },
};
export default nextConfig;Why transpilePackages?
.tsx source (the Turborepo “Just-in-Time” model), so Next.js needs to compile it like your own code. This keeps the components readable and Tailwind able to scan their class names.2 · New Vite + React app
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install @viliha/vui-ui
npm install -D tailwindcss @tailwindcss/viteimport { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({ plugins: [react(), tailwindcss()] });@import "tailwindcss";
@import "@viliha/vui-ui/theme.css";Vite transpiles the package's TypeScript automatically, with no extra config.
3 · Existing project
This manual wiring is exactly what npx @viliha/vui-ui init --existing --theme-only prints. It is the safe path that copies no files and touches no config. Do it by hand, or run that command and follow its output.
4 · Turborepo / monorepo
This is the package's native pattern (Vui Starter is itself a Turborepo). The one rule that matters: install and scaffold inside the target app (e.g. apps/web), never at the repo root. The root has no app/ and no Next.js app.
⚠️ Scaffold into the app, not the repo root
init against the specific app, either from inside it, or by naming it from the root. In monorepo mode the CLI does not auto-install (installs are workspace-specific), so install the deps in that app afterward.# from inside the app (simplest)
cd apps/web
npx @viliha/vui-ui init
# …or from the repo root, name the target app
npx @viliha/vui-ui init --turbo --dir apps/webcd apps/web
pnpm add @viliha/vui-ui # + the peer deps the CLI prints
# or from the root: pnpm --filter web add @viliha/vui-ui …
pnpm --filter web devHow do I use a component?
import { Button } from "@viliha/vui-ui/button";
import { Badge } from "@viliha/vui-ui/badge";
export function Example() {
return (
<div className="p-4">
<Badge variant="success">Active</Badge>
<Button variant="primary">Save</Button>
</div>
);
}