# Vue CDN vs Vue CLI: Key Differences for Maintainability and Performance

> Vue CDN or Vue CLI? Discover key differences in maintainability and performance. Learn when to use Vue CDN for prototypes vs. Vue CLI for production apps with optimized builds.

- Repository: [Vue/core](https://github.com/vuejs/core)
- Tags: tutorial
- Published: 2026-02-16

---

**Use the Vue CDN for rapid prototyping and small widgets, but choose the Vue CLI or Vite for production applications requiring tree-shaking, dependency management, and optimized build pipelines.**

When evaluating how to integrate Vue into your frontend project, understanding the architectural trade-offs between the **Vue CDN** global build and a full **Vue CLI** bundler workflow is critical for long-term success. According to the `vuejs/core` repository, these two approaches rely on fundamentally different distribution formats that directly impact bundle size, feature customization, and maintainability.

## Build Artifacts and Distribution Formats

The Vue core team ships distinct build artifacts tailored to these consumption methods. In [`packages/vue/README.md`](https://github.com/vuejs/core/blob/main/packages/vue/README.md), the documentation defines the **global build** ([`vue.global.js`](https://github.com/vuejs/core/blob/main/vue.global.js)) as an IIFE (Immediately Invoked Function Expression) that exposes a single `Vue` object on the window. This is the version served via CDN links like `https://unpkg.com/vue@3/dist/vue.global.prod.js`.

Conversely, the **ESM bundler build** ([`vue.runtime.esm-bundler.js`](https://github.com/vuejs/core/blob/main/vue.runtime.esm-bundler.js)) is designed for consumption by tools like webpack or Vite. As specified in [`packages/vue/package.json`](https://github.com/vuejs/core/blob/main/packages/vue/package.json), the `module` field points to this ESM variant, allowing the bundler to perform static analysis and dead-code elimination during the build process.

## Tree-Shaking and Bundle Size Optimization

The most significant performance divergence lies in **tree-shaking** capabilities. The Vue CDN global build bundles the entire runtime—and optionally the template compiler—into a single file with no mechanism to remove unused features. This means you ship the full Vue API surface to every user, regardless of whether you use features like the Options API or KeepAlive components.

In contrast, the `esm-bundler` build leverages [`packages/runtime-core/src/featureFlags.ts`](https://github.com/vuejs/core/blob/main/packages/runtime-core/src/featureFlags.ts) to expose compile-time flags. When using the Vue CLI or Vite, your bundler can inject these flags (such as `__VUE_OPTIONS_API__`) to enable aggressive dead-code elimination. This allows production bundles to exclude entire swaths of the Vue runtime, resulting in significantly smaller JavaScript payloads.

## Development Workflow and Tooling

The Vue CDN requires zero build configuration. You add a `<script>` tag to your HTML and immediately access the `Vue` global. This is ideal for rapid prototyping, legacy page enhancements, or environments where build tooling is restricted.

However, the Vue CLI (and its modern successor, Vite) provides a sophisticated development environment. Running `npm create vite@latest` scaffolds a project with Hot Module Replacement (HMR), TypeScript support via [`packages-private/vite-debug/tsconfig.json`](https://github.com/vuejs/core/blob/main/packages-private/vite-debug/tsconfig.json) configurations, and integrated linting. The [`scripts/dev.js`](https://github.com/vuejs/core/blob/main/scripts/dev.js) file in the Vue core repository itself demonstrates how the team uses these tooling advantages for their own development workflow.

## Maintainability in Production Applications

Long-term maintainability represents the most critical factor for choosing between these approaches. With the Vue CDN, dependency management becomes manual and fragile. You must manually update script URLs to upgrade Vue versions, and coordinating compatible versions of ecosystem libraries (Vue Router, Pinia, VueUse) requires loading multiple CDN scripts in the correct order without the safety of semantic versioning enforcement.

The Vue CLI workflow centralizes dependency management in [`package.json`](https://github.com/vuejs/core/blob/main/package.json). This enables reproducible builds, automated security updates via `npm audit`, and precise version pinning. When the core team releases updates to `vuejs/core`, you update a single version specifier rather than hunting for new CDN URLs across your HTML files.

## Runtime Performance Characteristics

From a runtime perspective, the Vue CDN global build delivers a larger initial download because it cannot eliminate unused code. On slower networks, this increases Time-to-Interactive (TTI). The bundler build, processed through the Vue CLI, produces optimized chunks that support code-splitting and lazy loading, delivering faster first-paints and reduced memory overhead.

Additionally, the global build hard-codes feature flags at the time the CDN file is generated. You cannot toggle `__VUE_PROD_DEVTOOLS__` or other runtime behaviors without switching to a different pre-built file. The bundler build allows you to inject custom feature flags during your build process, enabling precise control over the runtime characteristics of your application.

## Summary

- **Vue CDN** uses the global IIFE build ([`vue.global.js`](https://github.com/vuejs/core/blob/main/vue.global.js)) which ships the entire runtime without tree-shaking, making it ideal for prototypes but suboptimal for production performance.
- **Vue CLI/Vite** leverages the ESM bundler build ([`vue.runtime.esm-bundler.js`](https://github.com/vuejs/core/blob/main/vue.runtime.esm-bundler.js)) enabling dead-code elimination, feature-flag injection via [`packages/runtime-core/src/featureFlags.ts`](https://github.com/vuejs/core/blob/main/packages/runtime-core/src/featureFlags.ts), and significantly smaller bundle sizes.
- **Maintainability** differs drastically: CDN requires manual URL management for updates and ecosystem libraries, while CLI uses [`package.json`](https://github.com/vuejs/core/blob/main/package.json) for reproducible, version-controlled dependency management.
- **Development experience** with CLI includes HMR, TypeScript support, and optimized production builds via `vite build` or webpack, whereas CDN offers zero tooling but immediate execution.

## Frequently Asked Questions

### Can I use the Vue CDN for production applications?

While technically possible, using the Vue CDN for production is generally discouraged for applications requiring long-term maintainability. You lose the ability to tree-shake unused features, meaning users download the entire Vue runtime regardless of which APIs you actually use. Additionally, managing dependencies like Vue Router or Pinia via separate CDN scripts becomes fragile as versions drift, whereas a CLI-managed [`package.json`](https://github.com/vuejs/core/blob/main/package.json) ensures compatible, reproducible builds.

### How does tree-shaking work with the Vue CLI but not the CDN?

The Vue CLI (and Vite) uses the `esm-bundler` build of Vue, which exposes ES modules that static analysis tools can parse. When you import specific APIs like `import { ref, computed } from 'vue'`, the bundler traces these dependencies and eliminates unreachable code. In contrast, the CDN global build ([`vue.global.js`](https://github.com/vuejs/core/blob/main/vue.global.js)) is a pre-bundled IIFE that assigns everything to a single `window.Vue` object, making it impossible for browsers to determine which features are unused at load time.

### What are Vue feature flags and why do they matter for performance?

Feature flags are compile-time constants defined in [`packages/runtime-core/src/featureFlags.ts`](https://github.com/vuejs/core/blob/main/packages/runtime-core/src/featureFlags.ts) that control which Vue APIs are included in your final bundle. For example, setting `__VUE_OPTIONS_API__` to `false` allows the bundler to strip out all Options API support code, reducing bundle size. The CDN build hard-codes these flags during its own build process, so you cannot customize them. With the Vue CLI, you define these flags in your bundler configuration, enabling aggressive dead-code elimination tailored to your specific application needs.

### Is there a middle ground between CDN and full CLI setup?

Yes, you can use **ES Modules via CDN** as a hybrid approach. Instead of the global build, you can import Vue directly from a CDN using ES module syntax: `import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'`. This gives you modern module benefits without a local build step, though you still lack tree-shaking and feature-flag customization. For production applications, migrating to a Vite-based setup remains the recommended path for optimal performance and maintainability.