Cutting Vuetify 3 Bundle Size with Tree‑Shakable Imports
Vuetify 3's ES‑module exports let you import only the components you need, cutting the library's gzipped footprint from ~350 KB to under 80 KB. This post shows the import pattern, bundler settings, and a quick verification script.
17 Jan 2026, 05:12 UTC

The problem: Vuetify pulls in everything by default
When you add Vuetify 3 to a Vue 3 project and import the whole library (import Vuetify from 'vuetify'), the production JavaScript bundle grows by roughly 350 KB gzipped. On a mobile connection that extra weight can add seconds to first paint, and most apps only use a fraction of the component catalog.
Why tree shaking works in Vuetify 3
Vuetify 3 is published as an ES‑module package. Each component (e.g., VBtn, VCard) lives in its own file under vuetify/lib and is re‑exported from the package root. Modern bundlers (Vite, webpack 5 with experiments.outputModule) can follow these static imports and drop any module that isn’t referenced. The result: a typical app that only uses a handful of components shrinks the Vuetify contribution to under 80 KB gzipped.
Enabling tree‑shakable imports
1. Use named imports from the package root
// ❌ Legacy global plugin – defeats tree shaking
import Vuetify from 'vuetify'
app.use(Vuetify)
// ✅ Named import – only VBtn and its deps are bundled
import { VBtn } from 'vuetify'
app.component('VBtn', VBtn)
Register components locally (or via a tiny plugin that only registers what you import) instead of the global app.use(Vuetify) call.
2. Keep the bundler in ES‑module mode
- Vite: default configuration already preserves ES modules.
- webpack 5: add
experiments: { outputModule: true }towebpack.config.jsand ensuremoduleis set toesnextintsconfig.json/jsconfig.json.
3. Avoid side‑effect imports
Importing 'vuetify/styles' or the legacy path 'vuetify/lib/components/VBtn' can pull in the whole stylesheet or trigger CommonJS resolution, which blocks tree shaking. Import the main Sass file once in your entry point and let the bundler handle the rest.
Worked example: verify the size drop in a fresh Vite project
- Create a project (run in a terminal with Node ≥ 18):
npm create vite@latest vuetify-tree-shake -- --template vue cd vuetify-tree-shake npm install npm install vuetify@^3.0.0 - Replace
src/main.jswith a minimal tree‑shaken setup:import { createApp } from 'vue' import { VBtn } from 'vuetify' import 'vuetify/styles' // single Sass entry, still tree‑shakable for components import App from './App.vue' const app = createApp(App) app.component('VBtn', VBtn) app.mount('#app') - Use only
<VBtn>inApp.vue. - Build and analyze:
The visualizer should show onlynpm run build npx rollup-plugin-visualizer --open dist/assets/*.jsVBtnand its internal dependencies (e.g.,VDefaultsProvider,VProgressLinear) – noVCard,VDataTable, etc. - Compare gzipped size: run
gzip -c dist/assets/*.js | wc -cand note the result (expect ~70–90 KB). Then temporarily switch toimport Vuetify from 'vuetify'; app.use(Vuetify), rebuild, and measure again (expect ~300–350 KB).
Trade‑offs and limitations
- Theming SCSS is not tree‑shaken. The single
@use 'vuetify/settings'import brings all design tokens (colors, breakpoints, dark mode). This is intentional – tokens are tiny compared to component code. - Legacy imports break the optimization. Any
import VBtn from 'vuetify/lib/components/VBtn'or globalapp.use(Vuetify)forces the bundler to include the entire library. - Bundler configuration matters. If webpack outputs CommonJS (
outputModule: false) or you transpile ES modules to CJS via Babel, tree shaking stops working.
Actionable next step
Open your current Vuetify 3 project, locate the entry point, and replace the global plugin registration with named imports for the components you actually use. Run a production build (vite build or webpack --mode production) and inspect the output with rollup-plugin-visualizer or source-map-explorer. If the Vuetify slice of the bundle is still large, search for stray vuetify/lib imports or a lingering app.use(Vuetify) call. Removing those will usually recover the expected size reduction.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.