Options API vs Composition API differences
Options API is centered around the concept of a component instance (this) and typically aligns better with a class-based mental model from OOP languages. It is more beginner-friendly by abstracting away reactivity details and enforcing code organization via option groups. Composition API is centered around declaring reactive state variables directly in a function scope and composing state from multiple functions together. It is more free-form and requires understanding how reactivity works in Vue but enables more powerful patterns for organizing and reusing logic. Both API styles are fully capable of covering common use cases and are different interfaces powered by the exact same underlying system.
Vue usage recommendations by use case
For learning purposes, choose the API style that looks easier to understand. For production use: go with Options API if you are not using build tools or plan to use Vue primarily in low-complexity scenarios such as progressive enhancement. Go with Composition API and Single-File Components if you plan to build full applications with Vue.
Vue as a progressive framework
Vue is designed to be flexible and incrementally adoptable. Depending on use case, Vue can be used in different ways: enhancing static HTML without a build step, embedding as Web Components on any page, building Single-Page Applications (SPA), building Fullstack/Server-Side Rendering (SSR), creating Jamstack/Static Site Generation (SSG), and targeting desktop, mobile, WebGL, and even the terminal. The core knowledge about how Vue works is shared across all these use cases.
Vue definition and core features
Vue is a JavaScript framework for building user interfaces. It builds on top of standard HTML, CSS, and JavaScript and provides a declarative, component-based programming model. Vue has two core features: Declarative Rendering, which extends standard HTML with a template syntax that allows describing HTML output based on JavaScript state, and Reactivity, which automatically tracks JavaScript state changes and efficiently updates the DOM when changes happen.
Options API overview
With Options API, component logic is defined using an object of options such as data, methods, and mounted. Properties defined by options are exposed on this inside functions, which points to the component instance. The data() function returns reactive state properties, methods are functions that mutate state and trigger updates and can be bound as event handlers in templates, and lifecycle hooks like mounted() are called at different stages of a component's lifecycle.
Create Vue project with npm command
To scaffold a new Vue project with build setup based on Vite, run the command: npm create vue@latest
Create Vue project with pnpm command
To scaffold a new Vue project with pnpm, run the command: pnpm create vue@latest
Create Vue project with yarn command
To scaffold a new Vue project with yarn, use one of these commands depending on yarn version: yarn create vue (v1+), yarn create vue@latest (v2+), or yarn dlx create-vue@latest (v4.11+).
Create Vue project with bun command
To scaffold a new Vue project with bun, run the command: bun create vue@latest
Create-vue prompts for optional features
The create-vue scaffolding tool presents prompts for: Project name, Add TypeScript, Add JSX Support, Add Vue Router for Single Page Application development, Add Pinia for state management, Add Vitest for Unit testing, Add an End-to-End Testing Solution (Cypress/Nightwatch/Playwright), Add ESLint for code quality, Add Prettier for code formatting, and Add Vue DevTools 7 extension for debugging.
Install and run Vue development server with pnpm
After creating a Vue project, run: cd <your-project-name>, pnpm install, then pnpm run dev to start the development server.
Install and run Vue development server with yarn
After creating a Vue project, run: cd <your-project-name>, yarn, then yarn dev to start the development server.
Vue CDN alternatives
Besides unpkg, you can use other CDNs that serve npm packages to load Vue, such as jsdelivr or cdnjs.
Vue global build example with Options API
Example of using Vue from CDN with global build and Options API:
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<div id="app">{{ message }}</div>
<script>
const { createApp } = Vue
createApp({
data() {
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>
Vue global build example with Composition API
Example of using Vue from CDN with global build and Composition API:
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<div id="app">{{ message }}</div>
<script>
const { createApp, ref } = Vue
createApp({
setup() {
const message = ref('Hello vue!')
return {
message
}
}
}).mount('#app')
</script>
Vue ES module build URL
The Vue ES modules build is available at: https://unpkg.com/vue@3/dist/vue.esm-browser.js
Vue ES module example with Options API
Example of using Vue from CDN with ES modules build and Options API:
<div id="app">{{ message }}</div>
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
data() {
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>
Vue ES module example with Composition API
Example of using Vue from CDN with ES modules build and Composition API:
<div id="app">{{ message }}</div>
<script type="module">
import { createApp, ref } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
setup() {
const message = ref('Hello Vue!')
return {
message
}
}
}).mount('#app')
</script>
Using import maps with Vue
Import maps allow you to map bare module names like 'vue' to their CDN URLs. Add a script tag with type="importmap" containing JSON that maps 'vue' to the Vue ES modules URL, then you can use import statements like: import { createApp } from 'vue' in your module scripts.
Import map example with Vue and Options API
Example of using Vue with import maps and Options API:
<script type="importmap">
{
"imports": {
"vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
}
}
</script>
<div id="app">{{ message }}</div>
<script type="module">
import { createApp } from 'vue'
createApp({
data() {
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>
Import map example with Vue and Composition API
Example of using Vue with import maps and Composition API:
<script type="importmap">
{
"imports": {
"vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
}
}
</script>
<div id="app">{{ message }}</div>
<script type="module">
import { createApp, ref } from 'vue'
createApp({
setup() {
const message = ref('Hello Vue!')
return {
message
}
}
}).mount('#app')
</script>
Import Maps browser support requirement
Import Maps is a relatively new browser feature with limited support. It is only supported in Safari 16.4 and later, and other modern browsers with support indicated on caniuse.com/import-maps.
petite-vue as alternative to full Vue
For contexts where jQuery or Alpine.js might have been used in the past, vuejs/petite-vue is an alternative approach to consider instead of the full Vue when using Vue from a CDN without a build system.
ES modules cannot work over file:// protocol
ES modules have a security restriction and can only work over the http:// protocol, not the file:// protocol used when opening local files directly in a browser. To use ES modules locally, you must serve files over HTTP using a local HTTP server.
Start local HTTP server with npx serve
To serve HTML files over HTTP on your local machine, run: npx serve from the command line in the same directory where your HTML file is located. This enables ES modules to work on localhost.
Modular component structure example with ES modules
Example of splitting Vue application into modules:
index.html:
<div id="app"></div>
<script type="module">
import { createApp } from 'vue'
import MyComponent from './my-component.js'
createApp(MyComponent).mount('#app')
</script>
my-component.js with Options API:
export default {
data() {
return { count: 0 }
},
template: `<div>Count is: {{ count }}</div>`
}
Modular component structure example with Composition API
Example of splitting Vue application into modules with Composition API:
my-component.js:
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
return { count }
},
template: `<div>Count is: {{ count }}</div>`
}
VS Code extension for template string syntax highlighting
The es6-string-html VS Code extension provides syntax highlighting for HTML template strings in JavaScript files when prefixed with a /*html*/ comment.
Vue frameworks with SSR support
Frameworks that support Server-Side Rendering (SSR) and other features out-of-the-box include: Nuxt, Vike, Astro, and Quasar.
Recommendation on using Vue frameworks
The general recommendation is to use a Vue framework only if you need Server-Side Rendering (SSR). If you don't need SSR, use Vite directly as a simpler setup.
Vue frameworks typically use Vite
Most Vue frameworks use Vite under the hood. Directly using Vite instead of a framework provides a simpler setup if you don't need SSR, though frameworks offer additional features like UI themes.
Load Vue from CDN using unpkg
You can use Vue directly from a CDN by including: <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> in your HTML. This loads the global build of Vue where all top-level APIs are exposed as properties on the global Vue object.
Install and run Vue development server with bun
After creating a Vue project, run: cd <your-project-name>, bun install, then bun run dev to start the development server.
Generated Vue project uses Composition API by default
The example components in a newly generated Vue project are written using the Composition API and <script setup> syntax, rather than the Options API.
Recommended IDE for Vue development
Visual Studio Code with the Vue - Official extension (Vue.volar) is the recommended IDE setup for Vue development.
Node.js version requirement for Vue project creation
Node.js version ^22.18.0 or >=24.12.0 is required to scaffold a Vue Single Page Application using create-vue.
SFC recommended use cases
SFCs are the recommended approach for using Vue in Single-Page Applications (SPA), Static Site Generation (SSG), and any non-trivial frontend where a build step can be justified for better development experience (DX).
Single-File Components (SFC) definition
Vue Single-File Components (SFCs), abbreviated as *.vue files, are a special file format that encapsulates the template, logic, and styling of a Vue component in a single file.
SFC structure with three blocks
An SFC contains three main blocks: a <template> block for the view, a <script> block for logic, and a <style> block for styling. These three blocks encapsulate and colocate the view, logic and styling of a component in the same file.
Options API SFC example
```vue
<script>
export default {
data() {
return {
greeting: 'Hello World!'
}
}
}
</script>
<template>
<p class="greeting">{{ greeting }}</p>
</template>
<style>
.greeting {
color: red;
font-weight: bold;
}
</style>
```
This example shows a complete SFC using the Options API with template, script, and style blocks.
Composition API SFC example
```vue
<script setup>
import { ref } from 'vue'
const greeting = ref('Hello World!')
</script>
<template>
<p class="greeting">{{ greeting }}</p>
</template>
<style>
.greeting {
color: red;
font-weight: bold;
}
</style>
```
This example shows a complete SFC using the Composition API with <script setup> syntax.
Benefits of Single-File Components
SFCs provide numerous benefits: author modularized components using familiar HTML, CSS and JavaScript syntax; colocate inherently coupled concerns; use pre-compiled templates without runtime compilation cost; enable component-scoped CSS; provide more ergonomic syntax when working with Composition API; allow more compile-time optimizations by cross-analyzing template and script; offer IDE support with auto-completion and type-checking for template expressions; and provide out-of-the-box Hot-Module Replacement (HMR) support. These benefits offset the requirement that SFCs need a build step.
SFC compilation process
Vue SFCs are framework-specific file formats that must be pre-compiled by @vue/compiler-sfc into standard JavaScript and CSS. A compiled SFC becomes a standard JavaScript (ES) module that can be imported like any other module with proper build setup.
SFC import example
```js
import MyComponent from './MyComponent.vue'
export default {
components: {
MyComponent
}
}
```
This shows how to import an SFC as a standard JavaScript module in another component.
SFC development vs production style handling
<style> tags inside SFCs are typically injected as native <style> tags during development to support hot updates. For production, they can be extracted and merged into a single CSS file.
SFC tooling and build setup
In actual projects, the SFC compiler is typically integrated with a build tool such as Vite or Vue CLI (which is based on webpack). Vue provides official scaffolding tools to help you get started with SFCs quickly.
Separation of concerns in SFCs
Separation of concerns is not equal to the separation of file types. In modern UI development, dividing the codebase into loosely-coupled components is more effective than dividing into three huge layers (HTML/CSS/JS). Inside a component, the template, logic, and styles are inherently coupled, and colocating them makes the component more cohesive and maintainable.
Alternative to full SFC setup
Vue can still be used via plain JavaScript without a build step if SFCs feel like overkill. For enhancing largely static HTML with light interactions, petite-vue (a 6 kB subset of Vue) optimized for progressive enhancement can be used. You can also separate JavaScript and CSS into separate files using Src Imports while still leveraging SFC's hot-reloading and pre-compilation features.
SFC Playground
You can play with SFCs and explore how they are compiled in the Vue SFC Playground at https://play.vuejs.org/.
TypeScript in Vue reduces runtime errors and improves refactoring
A type system like TypeScript can detect many common errors via static analysis at build time. This reduces the chance of runtime errors in production and allows for more confident refactoring in large-scale applications. TypeScript also improves developer ergonomics through type-based auto-completion in IDEs.
Vue is written in TypeScript with first-class support
Vue is written in TypeScript itself and provides first-class TypeScript support. All official Vue packages come with bundled type declarations that should work out-of-the-box.
create-vue scaffolds TypeScript-ready Vue projects
create-vue, the official project scaffolding tool, offers options to scaffold a Vite-powered, TypeScript-ready Vue project.
Vite dev server performs transpilation-only with TypeScript
With a Vite-based setup, the dev server and bundler are transpilation-only and do not perform any type-checking. This ensures the Vite dev server stays blazing fast even when using TypeScript.
IDE setup recommended for instant type error feedback in development
During development, relying on a good IDE setup is recommended for instant feedback on type errors.
vue-tsc utility for command-line type checking
vue-tsc is a wrapper around tsc, TypeScript's own command line interface. It works largely the same as tsc except that it supports Vue SFCs in addition to TypeScript files. You can run vue-tsc in watch mode in parallel to the Vite dev server, or use a Vite plugin like vite-plugin-checker which runs the checks in a separate worker thread.
VS Code is strongly recommended for TypeScript with Vue
Visual Studio Code (VS Code) is strongly recommended for its great out-of-the-box support for TypeScript.
Vue - Official extension provides TypeScript support in SFCs
Vue - Official (previously Volar) is the official VS Code extension that provides TypeScript support inside Vue SFCs, along with many other great features. It replaces Vetur, the previous official VS Code extension for Vue 2. If you have Vetur currently installed, make sure to disable it in Vue 3 projects.
WebStorm provides out-of-the-box TypeScript and Vue support
WebStorm provides out-of-the-box support for both TypeScript and Vue. Other JetBrains IDEs support them too, either out of the box or via a free plugin. As of version 2023.2, WebStorm and the Vue Plugin come with built-in support for the Vue Language Server. You can set the Vue service to use Volar integration on all TypeScript versions under Settings > Languages & Frameworks > TypeScript > Vue. By default, Volar will be used for TypeScript versions 5.0 and higher.
create-vue includes pre-configured tsconfig.json
Projects scaffolded via create-vue include pre-configured tsconfig.json. The base config is abstracted in the @vue/tsconfig package. Inside the project, Project References are used to ensure correct types for code running in different environments (such as app code and test code which should have different global variables).
compilerOptions.isolatedModules set to true for Vite
compilerOptions.isolatedModules is set to true because Vite uses esbuild for transpiling TypeScript and is subject to single-file transpile limitations. compilerOptions.verbatimModuleSyntax is a superset of isolatedModules and is also a good choice—it is what @vue/tsconfig uses.