Vue.js is a progressive JavaScript framework for building user interfaces and single-page applications. Evan You created it and released it in 2014. Vue 3 is the current major version, and as of this writing the latest stable release on GitHub is 3.5.x. This guide gets you from zero to a working Vue 3 app, using the modern Composition API with <script setup>.
What Is Vue 3?
Vue 3 is the current major version of the Vue.js framework. It adds the Composition API for organizing logic in reusable functions called composables, a faster reactivity system based on proxies, first-class TypeScript support and the <script setup> syntax for single-file components. Vue is progressive: you can drop it into one page or build a full application with routing and state management.
If you are comparing frameworks, see how Svelte 5 compares to React and what SolidJS does differently. For a convention-heavy alternative, read what Ember.js is.
Why Choose Vue.js?
- Gentle learning curve. Templates look like HTML, and you can start with a script tag.
- Fine-grained reactivity. Vue tracks which state each part of a template uses and updates only what changed.
- Component-based. Single-file components keep template, logic and styles together.
- Incrementally adoptable. Use it for one widget or the whole app.
- Official ecosystem. Vue Router for routing and Pinia for state management are maintained by the Vue team.
- Good documentation. The official docs at vuejs.org cover both API styles.
Getting Started
Create a project
The official way is create-vue, which sets up Vite for you:
npm create vue@latestIt asks whether you want TypeScript, Vue Router, Pinia, Vitest and a linter, then scaffolds the project. Then:
cd my-vue-app
npm install
npm run devTry it from a CDN
For a quick experiment on a plain HTML page:
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>Core Concepts
Reactive state with ref
In the Composition API you declare state with ref (for single values) or reactive (for objects). Inside <script setup>, anything you declare is available in the template.
<script setup>
import { ref } from 'vue';
const count = ref(0);
function increment() {
count.value++;
}
</script>
<template>
<button @click="increment">Count: {{ count }}</button>
</template>In templates, Vue unwraps refs automatically, so you write count, not count.value. In JavaScript you use .value.
Computed values and watchers
computed caches a derived value and recalculates only when its dependencies change. watch runs a side effect when a source changes.
<script setup>
import { ref, computed, watch } from 'vue';
const message = ref('');
const isLong = computed(() => message.value.length > 5);
watch(message, (value) => {
console.log('Message changed to', value);
});
</script>
<template>
<input v-model="message" />
<p v-if="isLong">Message is long enough</p>
</template>Template directives
| Directive | Purpose |
|---|---|
v-bind (or :) | Bind an attribute to state |
v-model | Two-way binding for form inputs |
v-if, v-else, v-show | Conditional rendering |
v-for | Render a list |
v-on (or @) | Listen to events |
Components, props and emits
Each .vue file is a component. Declare props and events with defineProps and defineEmits:
<!-- Greeting.vue -->
<script setup>
const props = defineProps({
name: String,
});
const emit = defineEmits(['greeted']);
</script>
<template>
<h2 @click="emit('greeted')">Hello, {{ props.name }}!</h2>
</template>Use it from a parent:
<script setup>
import Greeting from './Greeting.vue';
</script>
<template>
<Greeting name="Alex" @greeted="console.log('clicked')" />
</template>Composables
A composable is a function that uses Vue's reactivity and returns state and helpers. It is the Composition API's answer to mixins.
// useCounter.js
import { ref } from 'vue';
export function useCounter(initial = 0) {
const count = ref(initial);
const increment = () => count.value++;
return { count, increment };
}Options API vs Composition API
Vue 3 supports both. The Options API (data, methods, computed) is still fully supported and fine for small components. The Composition API groups code by feature instead of by option type, which scales better and works better with TypeScript. New projects usually use <script setup>.
The Vue Ecosystem
Vue Router
The official router handles navigation, nested routes and route guards.
npm install vue-routerPinia
Pinia is the official state management library and the recommended choice for Vue 3. It replaced Vuex, which is now in maintenance mode.
npm install pinia// stores/counter.js
import { defineStore } from 'pinia';
import { ref } from 'vue';
export const useCounterStore = defineStore('counter', () => {
const count = ref(0);
function increment() {
count.value++;
}
return { count, increment };
});If you are weighing state libraries across frameworks, my Zustand vs Redux comparison covers the React side.
TypeScript
Vue 3 is written in TypeScript. With <script setup lang="ts"> you get typed props through defineProps<{ name: string }>() and typed emits. Run type checks in your editor with Volar and in CI with vue-tsc. Note that Vue single-file component checking depends on tooling that embeds the TypeScript compiler, so check compatibility before moving a Vue project to TypeScript 7 (see TypeScript 7).
What Is Vapor Mode?
Vapor Mode is an experimental compilation strategy for Vue that compiles components to direct DOM operations instead of using the virtual DOM. It targets less runtime code and better performance while keeping the same component syntax. As of this writing, Vapor Mode is part of the Vue 3.6 line, which is in release-candidate pre-release on GitHub, while the latest stable release is 3.5.x. Treat it as opt-in and check the Vue release notes before using it in production.
Frequently Asked
What is Vue 3? The current major version of Vue.js, built around the Composition API, a proxy-based reactivity system and TypeScript support.
Should I use the Options API or the Composition API? The Composition API with <script setup> for new code. The Options API is still supported and fine for simple components.
Is Vuex still used? Existing projects use it, but Pinia is the official recommendation for Vue 3.
Is Vapor Mode stable? Not yet as of this writing. It ships with the Vue 3.6 line, which is still a release candidate, while the stable release is 3.5.x.
How do I create a Vue 3 project? Run npm create vue@latest and follow the prompts.
If you want to go deeper, the official documentation at vuejs.org is excellent.