Library / SDK
vuetifyjs/0 avatar
vuetifyjs/0

Vuetify Zero: a headless Vue 3 layer that ships behaviour, not pixels

0️⃣ Composable UI engine for Vue. Build complex interfaces with reusable state, logic, and primitives—without being locked into components or styles.

741 stars10 forksTypeScriptNOASSERTION

At a glance

What is it?
Vuetify Zero, published as @vuetify/v0, is a headless component and composable library for Vue 3 that gives you state, logic and accessibility primitives without a rendered style, so the design system comes from a separate package. The stable 1.0.0 shipped in July 2026, and the CLI can seed styled examples from a docs registry into your project.
Who is it for?
Vuetify Zero is worth adopting if you are building a design system on Vue and want the behaviour layer written once, because the provider components for selection, locale, theme and step are the parts teams otherwise reinvent badly and the subpath exports keep the bundle small. It is the wrong tool if you want a component library you can install and use, because the whole premise is that it renders nothing and the styling has to come from somewhere else.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The package name is the version number and the licence file is separate

The package is published as @vuetify/v0, described as headless Vue 3 UI primitives and composables for building modern applications and design systems, and the README calls it the foundation of the Vuetify ecosystem, offering lightweight, unstyled building blocks with full TypeScript support and accessibility features built in.

The headless framing is the whole design decision. Importing a component gives you logic and accessibility, not a rendered UI, as the CLI section states plainly. There is no style, no theme applied by default and no opinion about how a button should look, so the appearance comes from somewhere else entirely.

That somewhere else is the second half of the monorepo. The repository is a pnpm monorepo containing the core package, a playground package, and three design system packages: @paper/emerald, described as the Emerald design system, @paper/bulma as a Bulma compatibility design system, and @paper/genesis as the Genesis design system for docs primitives. There is also @vuetify/paper, described as styling primitives and marked private and dormant, plus the docs app and a playground app.

The maintenance facts are worth stating clearly. The README says v0 is stable, that v1.0.0 shipped on July 22, 2026 and that the stable API surface is locked under SemVer, with the caveat that preview-level APIs flagged in the roadmap may still see documented changes. The last push was on 2026-10-20, and the release list shows v1.2.3 for the main package with @vuetify/play and @paper/genesis published on the same day.

One loose end: the repository licence field is recorded as a custom licence that GitHub cannot classify, while the badge and the README link point at a LICENSE.md file. Read that file rather than assuming the terms.

The CLI seeds styled examples because the library itself styles nothing

The tooling exists to solve the problem the headless approach creates. If importing a component gives you logic and accessibility but not a rendered UI, then getting a working screen means combining primitives with a design system, and that combination work is exactly what a developer would rather not repeat by hand.

The Vuetify CLI scaffolds projects and seeds working examples from the docs registry. Creating a project is two commands:

bash
pnpm create vuetify0
# or
pnpm dlx @vuetify/cli init

And the add command pulls a styled example into your project from the docs registry, either through an interactive picker or by naming the component:

bash
# Interactive picker
pnpm dlx @vuetify/cli add

# Seed a specific component
pnpm dlx @vuetify/cli add dialog

# Seed a composable plugin
pnpm dlx @vuetify/cli add use-theme

That the add command takes a composable name as well as a component name tells you something about the shape of the library. Composable plugins are first-class units that a project can pull in the same way as a component, which is consistent with a design where the behavioural layer is the product.

The CLI guide covers registry options, the vuetify.json tracking file and the full command list, which means the registry is a service with its own index at 0.vuetifyjs.com/registry/index.json rather than a folder in the repository.

For a team, the interesting property is that the seeded example is the documented one. Instead of writing a dialog from scratch and getting the focus management subtly wrong, you take the example the documentation site is built from, which is the version the maintainers test.

Subpath exports keep the bundle to what you actually import

The package publishes tree-shakeable subpath exports, and the list is worth reading because it shows how the library is divided.

ts
import { ... } from '@vuetify/v0'            // Everything
import { ... } from '@vuetify/v0/components' // Components only
import { ... } from '@vuetify/v0/composables' // Composables only
import { ... } from '@vuetify/v0/utilities'  // Utilities only
import { ... } from '@vuetify/v0/types'      // Types only
import { ... } from '@vuetify/v0/constants'  // Constants only
import { ... } from '@vuetify/v0/date'       // Date adapter and utilities

The separation of components, composables, utilities, types, constants and a date adapter means a project that only needs a date picker does not pull in the whole component set, and a project that only needs a utility does not pull in the components at all. The date subpath in particular is a separate concern, and a date adapter is the kind of thing that has to be swappable for localisation, since different regions format and order dates differently.

The tree-shaking claim is backed by tooling in the repository. There is a .size-limit.json file at the root, which is the configuration for a bundle size budget check, and the scripts include a metrics pipeline that runs coverage, builds the package, runs the benchmark and then feeds the result through a generate-metrics script. The benchmark scripts are configured for the v0:unit project with a single worker and no file parallelism, which is the correct way to benchmark and a detail that suggests the numbers are meant to be comparable between runs.

The package.json at the root is named @vuetify/zero and is marked private, with the version 1.0.0-beta.3, which is the monorepo root rather than the published package.

Provider components are where the design work actually lives

The component list is organised into groups, and the group that carries the most weight is Providers, not the visible controls.

The primitives are infrastructure. AspectRatio is a fixed width-to-height ratio container using CSS aspect-ratio. Atom is a polymorphic base element with a dynamic as prop and a renderless mode. Portal is a Teleport wrapper with automatic z-index stacking through useStack. Presence is an animation-agnostic mount lifecycle with lazy mounting and exit timing, which is the piece that makes a headless component work with whatever animation library the consuming application uses.

The providers are the state machines. Group provides multi-selection with tri-state support, which is the parent-checked-when-some-children-checked case. Selection provides multi-selection state with v-model binding. Single provides single-selection with automatic deselection. Step provides sequential navigation with first, last, next and prev. Locale is a locale context provider for internationalisation. Theme is a theme context provider with CSS variable injection. Scrim is an overlay backdrop with click-to-dismiss and z-index management.

This is the argument for a headless library in one list. Group, Selection, Single and Step are four selection and navigation models that every design system reimplements, usually badly, and they are exactly the parts where the accessibility semantics live, since a tri-state checkbox or a keyboard-navigable tab list is not something a styling layer can add on top.

The actions group is small on purpose. Button carries a loading grace period, toggle groups and icon accessibility. Toggle is a pressable on and off button with standalone and group modes.

The disclosure group is where modals live. Dialog uses the native dialog element with focus management, which means the browser's own modal behaviour does the trapping. AlertDialog is a confirmation dialog with deferred close and a wait() and close() pattern, which is the shape you need when a dialog must return a result to the code that opened it. Popover is CSS anchor-positioned popup content, and Tabs is tab panel navigation with keyboard support and lazy content.

Node 26 and pnpm 10.6 are a real cost of entry

The stated requirements are Node.js 26 or newer, pnpm 10.6 or newer, and Vue 3.5.0 or newer. Those floors are high enough that they will rule the library out for a substantial number of projects today, and it is worth saying so plainly rather than discovering it during an install.

Node 26 as a minimum is well ahead of the long term support lines most teams are still on, and it means the library cannot be consumed by an application whose build environment is pinned to an older Node for any reason. The pnpm floor of 10.6 has the same effect on a team that standardised on npm or yarn, since the monorepo itself is pnpm based and the published package is expected to be installed into a pnpm or npm or yarn project alike.

The Vue floor of 3.5.0 is more reasonable, and it is a good sign, since the Vue 3.5 line is where the reactivity system and the various performance work landed.

The installation instructions list four package managers, which is a sign of a package that is meant to be consumed rather than only used in its own monorepo:

bash
npm install @vuetify/v0@latest
# or
pnpm add @vuetify/v0
# or
yarn add @vuetify/v0
# or
bun add @vuetify/v0

The monorepo itself is pnpm based, with a pnpm-workspace.yaml and a pnpm-lock.yaml, and the root scripts use the pnpm filter syntax throughout, including a filter for the packages directory and one for the private playground. A .nvmrc file at the root pins the Node version the project develops against, which is the mechanism that keeps the declared minimum honest.

The repository is a serious one to look at as an engineering reference, with a .changeset directory for release notes, an AGENTS.md and a CLAUDE.md, a knip.json for unused dependency detection, a lychee.toml for link checking, a vitest config, an eslint flat config and a patches directory.

Editorial conclusion

Vuetify Zero is worth adopting if you are building a design system on Vue and want the behaviour layer written once, because the provider components for selection, locale, theme and step are the parts teams otherwise reinvent badly and the subpath exports keep the bundle small. It is the wrong tool if you want a component library you can install and use, because the whole premise is that it renders nothing and the styling has to come from somewhere else. Before you commit, verify three things yourself: that Node 26 or newer, pnpm 10.6 or newer and Vue 3.5.0 or newer are what your build environment provides, since those are the stated requirements, that the design system you intend to pair with it is one of the packages in the monorepo or your own, since Emerald, Bulma and Genesis are the shipped options, and that the preview-level APIs you plan to use are not on the roadmap's change list, because the stable surface is locked under SemVer but the preview-level surface is not.

Frequently asked questions

What is Vuetify Zero and what does it give you?

It is the @vuetify/v0 package, a headless Vue 3 library of UI primitives and composables. Importing a component gives you logic and accessibility rather than a rendered UI, so the styling comes from a separate design system such as Emerald, Bulma or Genesis.

How do I install Vuetify Zero and what are the requirements?

Install it with npm install @vuetify/v0@latest, pnpm add @vuetify/v0, yarn add @vuetify/v0 or bun add @vuetify/v0. The stated requirements are Node.js 26 or newer, pnpm 10.6 or newer, and Vue 3.5.0 or newer.

Is Vuetify Zero stable?

The README states that v0 is stable, that v1.0.0 shipped on July 22, 2026 and that the stable API surface is locked under SemVer. Preview-level APIs flagged in the roadmap may still see documented changes.

How do I get styled examples for a headless component?

Use the Vuetify CLI, for example pnpm dlx @vuetify/cli add dialog to seed a specific component or pnpm dlx @vuetify/cli add use-theme to seed a composable plugin, with the interactive picker available as pnpm dlx @vuetify/cli add. Examples come from the docs registry.

Which design systems ship with Vuetify Zero?

The monorepo contains @paper/emerald as the Emerald design system, @paper/bulma as a Bulma compatibility design system and @paper/genesis as the Genesis design system for docs primitives, plus @vuetify/paper for styling primitives, which is marked private and dormant.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. vuetifyjs/0 on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/vuetifyjs-0.svg)](https://hysenlabs.com/projects/vuetifyjs-0)

Was this useful?