What’s New in Vue 3? A Deep Dive into Architecture, Reactivity, and Vite

This article provides a comprehensive overview of Vue 3, covering its evolution from Vue 2, key new features such as TypeScript support, the Composition API, performance optimizations, the modular monorepo structure, the reactivity system built on Proxy, and the Vite development server that powers its ecosystem.

QQ Music Frontend Team
QQ Music Frontend Team
QQ Music Frontend Team
What’s New in Vue 3? A Deep Dive into Architecture, Reactivity, and Vite

Brief Introduction to Vue 3.0

Vue 3.0, one of the major front‑end events of 2020, was officially released. Compared with Vue 2, Vue 3 introduces substantial changes in implementation principles and usage. The article is divided into two parts: a brief overview of Vue 3.0 and an analysis of its reactivity source code.

The Evolution of Vue 3

Vue 2.0 launched in 2016 and enjoyed rapid community growth. Over four years, front‑end technologies such as TypeScript and Lerna became mainstream, prompting Vue developers to adopt them. With ES6 standardization and increasingly complex front‑end applications, limitations in Vue 2’s architecture emerged, leading to the initiation of Vue 3 development, which progressed through four stages:

Prototype Design (2018/02 – 2018/09) : Experimented with TypeScript, Lerna, and built a mini v‑dom runtime and a Proxy‑based reactive API.

Exploration (2018/09 – 2019/05) : Explored class API, TypeScript, Reactive Hooks, Time Slicing, and new render strategies; milestone – class API RFC.

Pivot – Core Development (2019/05 – 2019/08) : Dropped class API, rewrote render logic; milestones – Function API RFC and Composition API RFC.

Feature Parity : Focused on supporting Vue 2 APIs, optimizing v‑model, transition system, and SFC HMR.

Vue 3 vs Vue 2

Vue 3 brings several major improvements:

Implemented in TypeScript, offering better maintainability and native TypeScript support.

Modular monorepo architecture using Lerna; each package has independent API, type definitions, and tests.

Vue 3 monorepo package structure
Vue 3 monorepo package structure

The key packages and their responsibilities are:

compiler-core : Platform‑agnostic compiler with extensible core features.

compiler-dom : Browser‑specific compiler built on compiler‑core.

compiler-sfc : Compiles single‑file components.

compiler-ssr : Server‑side rendering compiler.

reactivity : Stand‑alone reactive system usable with any framework.

runtime-core : Platform‑agnostic runtime supporting virtual DOM and component APIs.

runtime-dom : Browser runtime handling native DOM, events, etc.

runtime-test : Lightweight runtime for testing and DOM serialization.

server-renderer : Server‑side rendering entry.

shared : Common utilities and constants.

size-check : Private package for bundle size checking.

template-explorer : Real‑time component compilation in the browser.

vue : Full‑featured Vue build that combines runtime and compiler.

global.d.ts : Global TypeScript declarations.

Composition API : Introduces a new way to write components, replacing the Options API.

Composition API example
Composition API example

In Vue 2, a component using the Options API might look like this:

<script>
export default {
  data() { return { message: 'Hello' } },
  methods: { greet() { console.log(this.message) } }
}
</script>

In Vue 3, the same component can be written with the Composition API:

<script setup>
import { ref } from 'vue'
const message = ref('Hello')
function greet() { console.log(message.value) }
</script>

The Composition API improves readability, maintainability, and reusability, especially for complex components.

Performance Optimizations

Vue 3 achieves significant size and speed gains through tree‑shaking, static hoisting, block‑based rendering, and PatchFlags. Benchmarks show roughly 41% reduction in bundle size, 55% faster initial render, 33% faster updates, and 54% lower memory usage.

Performance comparison chart
Performance comparison chart

Vue 3’s compiler marks dynamic nodes with PatchFlags, allowing the runtime to update only those nodes. Blocks group dynamic children, enabling targeted updates without traversing the entire virtual DOM.

New Features in Vue 3

Teleport, provide/inject, and Suspense for advanced component patterns.

Vite as the default development server, leveraging native ESM for instant cold starts, on‑demand compilation, and fast HMR.

Vite works by serving modules directly to the browser, intercepting import requests, and rewriting bare module specifiers with an @modules prefix to resolve them from node_modules. It also handles Vue, CSS, and TypeScript files via dedicated plugins.

<script type="module">
import { createApp } from './main.js'
createApp()
</script>

Overall, Vue 3 offers better performance, a more modern architecture, and a developer‑friendly ecosystem.

Vue 3.0 Reactivity Source Code Analysis and Manual Implementation

Prerequisite Knowledge

Before diving into Vue 3’s reactivity, it helps to understand Vue 2’s data binding, which relied on Object.defineProperty to intercept getters and setters, recursively traversing objects and patching array prototype methods.

Reflect & Proxy

Vue 3’s reactivity leverages ES6 Reflect and Proxy. A Proxy wraps a target object and intercepts operations via handler traps; Reflect performs the default behavior inside those traps. This enables a publish‑subscribe model where data changes trigger view updates.

Source Code Overview

The reactivity API is exported from the reactivity package and includes reactive, ref, computed, and effect. The focus here is on reactive, which creates a Proxy‑based reactive copy of an object.

function reactive(target) {
  if (isReadonly(target)) return target
  return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers)
}
createReactiveObject

checks the target’s type, ensures it is observable, and then creates a new Proxy with either baseHandlers or collectionHandlers depending on whether the target is a collection (Map/Set) or a plain object.

function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers) {
  if (!isObject(target)) return target
  const existing = (isReadonly ? readonlyMap : reactiveMap).get(target)
  if (existing) return existing
  const targetType = getTargetType(target)
  if (targetType === TargetType.INVALID) return target
  const proxy = new Proxy(target, targetType === TargetType.COLLECTION ? collectionHandlers : baseHandlers)
  (isReadonly ? readonlyMap : reactiveMap).set(target, proxy)
  return proxy
}

The mutableHandlers object defines get, set, deleteProperty, has, and ownKeys traps. The get trap performs dependency tracking via track, while the set trap triggers updates through trigger. For collections, only a custom get is needed.

const mutableHandlers = { get, set, deleteProperty, has, ownKeys }
const mutableCollectionHandlers = { get: createInstrumentationGetter(false, false) }

The get implementation checks for special keys, handles array instrumentations, collects dependencies with track, unwraps ref values, and recursively proxies nested objects.

function get(target, key, receiver) {
  if (key === ReactiveFlags.IS_REACTIVE) return true
  const res = Reflect.get(target, key, receiver)
  if (!isReadonly) track(target, TrackOpTypes.GET, key)
  if (isObject(res)) return isReadonly ? readonly(res) : reactive(res)
  return res
}

The set trap determines whether a property is being added or updated, then calls trigger with the appropriate operation type.

function set(target, key, value, receiver) {
  const oldValue = target[key]
  const result = Reflect.set(target, key, value, receiver)
  if (target === toRaw(receiver)) {
    if (!hasKey) trigger(target, TriggerOpTypes.ADD, key, value)
    else if (hasChanged(value, oldValue)) trigger(target, TriggerOpTypes.SET, key, value, oldValue)
  }
  return result
}

Through these mechanisms, Vue 3 achieves fine‑grained reactivity with minimal overhead compared to Vue 2’s recursive Object.defineProperty approach.

References

The Process: Making Vue 3 – https://increment.com/frontend/making-vue-3/

Vue3 Compiler Optimization Details – https://zhuanlan.zhihu.com/p/150732926

Vite Design – https://github.com/zhangyuang/vite-design

Do We Still Need Webpack with Vite? – https://zhuanlan.zhihu.com/p/150083887

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaScriptComposition APIViteVue 3reactivity
QQ Music Frontend Team
Written by

QQ Music Frontend Team

QQ Music Web Frontend Team

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.