npm

Getting started

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/postcss

react and react-domare peer dependencies, so your app's versions are used (React 18 or 19).

Not using React?

The theme is plain CSS and ships on its own as @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 init

For 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 dev

The 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:

flags
--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 writing

Fresh projects: skip --src-dir

The scaffold uses a root 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.
  • Fresh + pre-built: full runnable app (config + shell + demo pages).
  • Fresh + theme-only: just globals.css + next.config wiring; build your own pages.
  • Existing + pre-built: shell + demo added; your config is never overwritten.
  • Existing + theme-only: nothing copied; prints the wiring steps.

⚠️ Installing into an existing project? Read this

Always pass --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):

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

next.config.ts
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?

The package ships .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

terminal
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install @viliha/vui-ui
npm install -D tailwindcss @tailwindcss/vite
vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({ plugins: [react(), tailwindcss()] });
src/index.css
@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.

  • Install the package, then confirm you're on Tailwind CSS v4.
  • Add @import "@viliha/vui-ui/theme.css"; after @import "tailwindcss";.
  • Next.js: add transpilePackages: ["@viliha/vui-ui"]. Vite: nothing extra. Other bundlers: ensure node_modules/@viliha/vui-ui is transpiled.
  • Already define shadcn tokens (--primary, …)? Import the theme first and override after, or remove the duplicates.

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

Run 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.
scaffold into apps/web
# 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/web
then install the deps in that app
cd 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 dev
  • Add transpilePackages: ["@viliha/vui-ui"], the theme.css import, and the @/* alias to that app: its next.config, globals.css, and tsconfig.json, not the root.
  • Confirm the app is covered by your workspace globs.
  • No build/dts step; the package is consumed as source, so Turborepo caches your app build, not a library build.

How do I use a component?

example.tsx
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>
  );
}