Skip to main content
Vuetify0 v1.0 is here
Vuetify0 Logo
Theme
Mode
Palettes
Accessibility
Vuetify One
Sign in to Vuetify One

Access premium tools across the Vuetify ecosystem — Bin, Play, Studio, and more.

Not a subscriber? See what's included

Tree-Shaking

v0 is fully tree-shakeable. Import what you need — unused code is eliminated during bundling. No configuration required.

Edit this page
Report a Bug
Copy Markdown

IntermediateJul 13, 2026
Tip

v0 has no side effects that prevent tree-shaking. Modern bundlers (Vite, Rollup, webpack 5) handle this automatically.

Import Strategies

v0 provides two ways to import: root imports and subpath imports. Both tree-shake correctly.

Root Imports

ts
import { createSelection, useTheme, Atom } from '@vuetify/v0'

The simplest approach. Your bundler eliminates everything you don’t use. This is the recommended default for most applications.

Subpath Imports

ts
import { createSelection } from '@vuetify/v0/composables'
import { Atom } from '@vuetify/v0/components'
import { isObject } from '@vuetify/v0/utilities'
import { IN_BROWSER } from '@vuetify/v0/constants'
import type { ID } from '@vuetify/v0/types'

Subpath imports narrow the module scope, giving bundlers less work to analyze. The size difference is negligible (well under 0.1 KB gzip in current builds) but subpaths can improve build speed on large projects.

Adapter Subpaths

Composables with optional adapters have dedicated subpaths that isolate their dependencies. Prefer these over root imports when you need a hard boundary around peer-heavy entry points:

ts
import { useDate } from '@vuetify/v0/date'
import { useFeatures } from '@vuetify/v0/features'
import { useStorage } from '@vuetify/v0/storage'
import { useTheme } from '@vuetify/v0/theme'
import { useLocale } from '@vuetify/v0/locale'
import { useLogger } from '@vuetify/v0/logger'
import { usePermissions } from '@vuetify/v0/permissions'
import { useNotifications } from '@vuetify/v0/notifications'
import { useRules } from '@vuetify/v0/rules'
import { createDataTable } from '@vuetify/v0/data-table'
import { material } from '@vuetify/v0/palettes/material/generate'

Nested adapter packages (e.g. @vuetify/v0/features/adapters/flagsmith, @vuetify/v0/locale/adapters/vue-i18n) hang off these entry points. These subpaths are primarily useful for framework authors who want to guarantee that adapter peer dependencies (like date-fns or flagsmith) don’t leak into consumer bundles.

Bundle Size

All sizes measured with Vue externalized (v0 code only), minified with esbuild.

What Things Cost

ImportRawGzip
Constants (IN_BROWSER, SUPPORTS_TOUCH)0.4 KB0.3 KB
Utilities (isObject, mergeDeep, clamp)0.7 KB0.4 KB
Single composable (createSelection)12.1 KB4.9 KB
Single composable + component (SelectionRoot, SelectionItem)17.3 KB6.8 KB
Deep chain (createStepcreateSinglecreateSelectioncreateRegistry)14.4 KB5.8 KB
6 composables (createSelection, createSingle, createGroup, createStep, createRegistry, useStorage)19.0 KB7.4 KB
4 component families (Selection, Dialog, Checkbox, Tabs)43.5 KB14.4 KB
Everything (import *)297.8 KB81.2 KB
Tip

A single composable is 4% of the full library. Most apps use a fraction of v0.

Composable Sharing

Composables share internal code. Adding more composables doesn’t multiply cost linearly — they reuse the same foundation layer (registry, context, utilities).

Composablesv0 Cost (gzip)Per-Composable
14.9 KB4.9 KB
67.4 KB1.2 KB

Root vs Subpath

ScenarioRootSubpathDifference
Single composable4.9 KB4.9 KB0.0 KB
6 composables7.4 KB7.4 KB0.0 KB

The difference is negligible — current builds produce byte-identical output regardless of entry point. Use whichever import style you prefer.

Dead Code Elimination

Unused imports are eliminated even without subpaths:

ts
// Only createSelection is used — the rest is removed
import {
  createSelection,
  createGroup,     // dead code
  createStep,      // dead code
  useStorage,      // dead code
  createTokens,    // dead code
} from '@vuetify/v0'

const [use, provide, ctx] = createSelection()

This produces the same bundle size as importing only createSelection.

How It Works

v0’s tree-shaking relies on three mechanisms:

1. ESM Exports

v0 ships ES modules with individual exports. Bundlers can statically analyze which exports are used and eliminate the rest.

2. Side-Effect-Free Annotations

Utility functions are annotated with /*#__NO_SIDE_EFFECTS__*/ so bundlers know they’re safe to remove when unused:

ts
/*#__NO_SIDE_EFFECTS__*/
function isObject(value: unknown): value is object {
  return typeof value === 'object' && value !== null && !Array.isArray(value)
}

3. Subpath Exports

The package.json defines subpath exports↗︎ that map to individual entry points. The block below is a representative excerpt — the published map is much larger (adapters, palettes, nested data-table paths, and more). For the isolation-oriented imports that matter day to day, see Adapter Subpaths.

json
{
  "exports": {
    ".": "./dist/index.mjs",
    "./components": "./dist/components/index.mjs",
    "./composables": "./dist/composables/index.mjs",
    "./utilities": "./dist/utilities/index.mjs",
    "./constants": "./dist/constants/index.mjs",
    "./types": "./dist/types/index.mjs",
    "./date": "./dist/date/index.mjs",
    "./theme": "./dist/theme/index.mjs"
  }
}

Verifying Your Bundle

Use rollup-plugin-visualizer↗︎ to inspect what v0 code ends up in your bundle:

vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { visualizer } from 'rollup-plugin-visualizer'

export default defineConfig({
  plugins: [
    vue(),
    visualizer({ open: true }),
  ],
})

Run vite build and a treemap opens in your browser showing exactly which v0 modules are included.

Discord
Need help? Join our community for support and discussions ↗
Was this page helpful?

© 2016-1970 Vuetify, LLC
Services
Ctrl+/