v1.11.8
See CHANGELOG.md for details.
@formatjs/unplugin: 1.2.3
- fix(deps): update dependency eslint-plugin-formatjs to v6.4.17 by @renovate[bot] in https://github.com/formatjs/formatjs/pull/6885
- fix(deps): update formatjs monorepo by @renovate[bot] in https://github.com/formatjs/formatjs/pull/6886
- chore(deps): update dependency vite to v8.1.4 by @renovate[bot] in https://github.com/formatjs/formatjs/pull/6887
- chore(deps): update dependency @babel/types to v8.0.4 by @renovate[bot] in https://github.com/formatjs/formatjs/pull/6888
- chore(deps): update dependency lucide-react to v1.24.0 by @renovate[bot] in https://github.com/formatjs/formatjs/pull/6889
- fix(@formatjs/intl-datetimeformat): apply Date method defaults by @longlho in https://github.com/formatjs/formatjs/pull/6893
- chore(deps): update rust crate regex to v1.13.0 by @renovate[bot] in https://github.com/formatjs/formatjs/pull/6890
- chore(deps): update pnpm to v11.11.0 by @renovate[bot] in https://github.com/formatjs/formatjs/pull/6892
- chore: release main by @longlho in https://github.com/formatjs/formatjs/pull/6894
- fix(@formatjs/unplugin): parse module ids with queries by @longlho in https://github.com/formatjs/formatjs/pull/6896
- fix(deps): update dependency eslint-plugin-formatjs to v6.4.18 by @renovate[bot] in https://github.com/formatjs/formatjs/pull/6900
- fix(deps): update dependency babel-plugin-formatjs to v11.3.16 by @renovate[bot] in https://github.com/formatjs/formatjs/pull/6899
Full Changelog: https://github.com/formatjs/formatjs/compare/@formatjs/unplugin@1.2.2...@formatjs/unplugin@1.2.3
v3.6.0-rc.1
Vue 3.6 is now entering the RC phase as we have completed the intended feature set for Vapor Mode.
3.6 also includes a major refactor of @vue/reactivity based on alien-signals, which significantly improves the reactivity system's performance and memory usage.
For more details about Vapor Mode, see the About Vapor Mode section later in this release note.
- hydration: avoid resolving inherited fallback in forwarded slots (4c215b5)
- hydration: remove adopted SSR DOM for unresolved async setup (3859af4)
- runtime-vapor: avoid patching invalid VNode slot content (25f5a8a)
- runtime-vapor: clean up detached slot branches (b41009d)
- runtime-vapor: defer slot content anchors during hydration (9b9e4bd)
- runtime-vapor: preserve outer pending slot anchors (4af4bf9)
- runtime-vapor: preserve slot content anchors during mismatch recovery (26f90b5)
- runtime-vapor: preserve v-show transition on vdom child (#15074) (fe882c9), closes #15073
- runtime-vapor: preserve vapor slot owner during interop slot dry run (#15031) (340630e)
- runtime-vapor: preserve VNode anchors in dynamic component hydration (898e2ca)
- runtime-vapor: remove unsafe slot dry runs from vdom interop (#15089) (3d42cdf), closes #14793
- runtime-vapor: reuse hydration anchor candidates (06778e7)
- vapor: handle v-if and v-show on transition roots (#15069) (8f62f2e), closes #15068
Vapor Mode is a new compilation mode for Vue Single-File Components (SFCs) with the goal of reducing baseline bundle size and improving performance.
It is 100% opt-in and supports a subset of existing Vue APIs with mostly identical behavior. Features that depend on VNodes or the component public instance proxy are not available in Vapor components.
Vapor Mode has demonstrated the same level of performance as Solid and Svelte 5 in third-party benchmarks.
Vapor Mode is feature-complete in Vue 3.6 RC. For now, we recommend using it in the following cases:
- Partial usage in existing apps, such as implementing a performance-sensitive page in Vapor Mode.
- Building small new apps entirely in Vapor Mode.
Vapor Mode supports template-only SFCs and SFCs using <script setup>; the Options API is not supported. The following forms are supported:
<script setup vapor>
// ...
</script>
<script vapor> is shorthand for <script setup vapor>:
<script vapor>
// ...
</script>
The vapor marker can also be placed on the template, enabling Vapor compilation for the entire SFC:
<template vapor>
<!-- ... -->
</template>
Applications composed entirely of Vapor components can use createVaporApp():
import { createVaporApp } from 'vue'
import App from './App.vue'
createVaporApp(App).mount('#app')
Apps created this way avoid pulling in the Virtual DOM runtime code and allow the baseline bundle size to be drastically reduced.
To use Vapor components in a VDOM app instance created via createApp(), the vaporInteropPlugin must be installed:
import { createApp, vaporInteropPlugin } from 'vue'
import App from './App.vue'
createApp(App).use(vaporInteropPlugin).mount('#app')
A Vapor app instance can also install vaporInteropPlugin to allow VDOM components to be used inside, but this pulls in the VDOM runtime and offsets the benefits of a smaller bundle.
Components authored with render functions or JSX remain VDOM components and also require interop when used in a Vapor application.
When the interop plugin is installed, Vapor and non-Vapor components can be nested inside each other. This currently covers standard props, events, and slots usage, but does not yet account for all possible edge cases. For example, there may still be rough edges when using a VDOM-based component library in Vapor Mode.
In general, we recommend having distinct regions in an app where one rendering mode or the other is used, and avoiding mixed nesting as much as possible.
By design, Vapor Mode supports a subset of existing Vue features. For the supported subset, we aim to deliver the same behavior according to the API specifications. The following features are currently unsupported or do not apply to Vapor Mode:
- Options API
app.config.globalPropertiesgetCurrentInstance()returnsnullin Vapor components@vue:xxxper-element lifecycle eventsv-memo- Component template refs do not expose properties such as
$el,$props,$attrs,$slots, and$refs
Vapor delegates eligible events to document. Each element stores its own handler, and a single document listener walks the event path and invokes matching handlers.
If any ancestor calls stopPropagation(), the event never reaches document, and the delegated handler will not run.
The following forms bypass delegation and attach the listener directly to the element:
<button @[event]="onClick" />
<button v-bind="{ onClick }" />
<button v-on="{ click: onClick }" />
In Vapor, slots.default() is not a side-effect-free inspection API. Calling it executes the slot's rendering logic, which may create Blocks and DOM nodes, register reactive effects, and claim existing SSR DOM during hydration.
Do not call a slot to inspect its output before deciding what else to render:
<script setup vapor>
import { useSlots } from 'vue'
const slots = useSlots()
const content = slots.default?.()
const showFallback = !content
</script>
<template>
<div v-if="showFallback">Fallback</div>
</template>
Instead, leave slot rendering to the template:
<template>
<slot />
</template>
Custom directives in Vapor also have a different interface:
type VaporDirective = (
node: Element | VaporComponentInstance,
value?: () => any,
argument?: string,
modifiers?: DirectiveModifiers,
) => (() => void) | void
value is a reactive getter that returns the binding value. Reactive effects can be set up using watchEffect() and are automatically released when the component unmounts. A directive may also return a cleanup function:
const MyDirective = (el, source) => {
watchEffect(() => {
el.textContent = source()
})
return () => console.log('cleanup')
}
Vapor Mode attempts to match VDOM Mode behavior as much as possible, but minor inconsistencies may still exist in edge cases because the two rendering modes are fundamentally different. In general, a minor inconsistency is not considered a breaking change unless the behavior has previously been documented.
For stable releases, please refer to CHANGELOG.md for details. For pre-releases, please refer to CHANGELOG.md of the minor branch.
v3.6.0-rc.1
Vue 3.6 is now entering the RC phase as we have completed the intended feature set for Vapor Mode.
3.6 also includes a major refactor of @vue/reactivity based on alien-signals, which significantly improves the reactivity system's performance and memory usage.
For more details about Vapor Mode, see the About Vapor Mode section later in this release note.
- hydration: avoid resolving inherited fallback in forwarded slots (4c215b5)
- hydration: remove adopted SSR DOM for unresolved async setup (3859af4)
- runtime-vapor: avoid patching invalid VNode slot content (25f5a8a)
- runtime-vapor: clean up detached slot branches (b41009d)
- runtime-vapor: defer slot content anchors during hydration (9b9e4bd)
- runtime-vapor: preserve outer pending slot anchors (4af4bf9)
- runtime-vapor: preserve slot content anchors during mismatch recovery (26f90b5)
- runtime-vapor: preserve v-show transition on vdom child (#15074) (fe882c9), closes #15073
- runtime-vapor: preserve vapor slot owner during interop slot dry run (#15031) (340630e)
- runtime-vapor: preserve VNode anchors in dynamic component hydration (898e2ca)
- runtime-vapor: remove unsafe slot dry runs from vdom interop (#15089) (3d42cdf), closes #14793
- runtime-vapor: reuse hydration anchor candidates (06778e7)
- vapor: handle v-if and v-show on transition roots (#15069) (8f62f2e), closes #15068
Vapor Mode is a new compilation mode for Vue Single-File Components (SFCs) with the goal of reducing baseline bundle size and improving performance.
It is 100% opt-in and supports a subset of existing Vue APIs with mostly identical behavior. Features that depend on VNodes or the component public instance proxy are not available in Vapor components.
Vapor Mode has demonstrated the same level of performance as Solid and Svelte 5 in third-party benchmarks.
Vapor Mode is feature-complete in Vue 3.6 RC. For now, we recommend using it in the following cases:
- Partial usage in existing apps, such as implementing a performance-sensitive page in Vapor Mode.
- Building small new apps entirely in Vapor Mode.
Vapor Mode supports template-only SFCs and SFCs using <script setup>; the Options API is not supported. The following forms are supported:
<script setup vapor>
// ...
</script>
<script vapor> is shorthand for <script setup vapor>:
<script vapor>
// ...
</script>
The vapor marker can also be placed on the template, enabling Vapor compilation for the entire SFC:
<template vapor>
<!-- ... -->
</template>
Applications composed entirely of Vapor components can use createVaporApp():
import { createVaporApp } from 'vue'
import App from './App.vue'
createVaporApp(App).mount('#app')
Apps created this way avoid pulling in the Virtual DOM runtime code and allow the baseline bundle size to be drastically reduced.
To use Vapor components in a VDOM app instance created via createApp(), the vaporInteropPlugin must be installed:
import { createApp, vaporInteropPlugin } from 'vue'
import App from './App.vue'
createApp(App).use(vaporInteropPlugin).mount('#app')
A Vapor app instance can also install vaporInteropPlugin to allow VDOM components to be used inside, but this pulls in the VDOM runtime and offsets the benefits of a smaller bundle.
Components authored with render functions or JSX remain VDOM components and also require interop when used in a Vapor application.
When the interop plugin is installed, Vapor and non-Vapor components can be nested inside each other. This currently covers standard props, events, and slots usage, but does not yet account for all possible edge cases. For example, there may still be rough edges when using a VDOM-based component library in Vapor Mode.
In general, we recommend having distinct regions in an app where one rendering mode or the other is used, and avoiding mixed nesting as much as possible.
By design, Vapor Mode supports a subset of existing Vue features. For the supported subset, we aim to deliver the same behavior according to the API specifications. The following features are currently unsupported or do not apply to Vapor Mode:
- Options API
app.config.globalPropertiesgetCurrentInstance()returnsnullin Vapor components@vue:xxxper-element lifecycle eventsv-memo- Component template refs do not expose properties such as
$el,$props,$attrs,$slots, and$refs
Vapor delegates eligible events to document. Each element stores its own handler, and a single document listener walks the event path and invokes matching handlers.
If any ancestor calls stopPropagation(), the event never reaches document, and the delegated handler will not run.
The following forms bypass delegation and attach the listener directly to the element:
<button @[event]="onClick" />
<button v-bind="{ onClick }" />
<button v-on="{ click: onClick }" />
In Vapor, slots.default() is not a side-effect-free inspection API. Calling it executes the slot's rendering logic, which may create Blocks and DOM nodes, register reactive effects, and claim existing SSR DOM during hydration.
Do not call a slot to inspect its output before deciding what else to render:
<script setup vapor>
import { useSlots } from 'vue'
const slots = useSlots()
const content = slots.default?.()
const showFallback = !content
</script>
<template>
<div v-if="showFallback">Fallback</div>
</template>
Instead, leave slot rendering to the template:
<template>
<slot />
</template>
Custom directives in Vapor also have a different interface:
type VaporDirective = (
node: Element | VaporComponentInstance,
value?: () => any,
argument?: string,
modifiers?: DirectiveModifiers,
) => (() => void) | void
value is a reactive getter that returns the binding value. Reactive effects can be set up using watchEffect() and are automatically released when the component unmounts. A directive may also return a cleanup function:
const MyDirective = (el, source) => {
watchEffect(() => {
el.textContent = source()
})
return () => console.log('cleanup')
}
Vapor Mode attempts to match VDOM Mode behavior as much as possible, but minor inconsistencies may still exist in edge cases because the two rendering modes are fundamentally different. In general, a minor inconsistency is not considered a breaking change unless the behavior has previously been documented.
For stable releases, please refer to CHANGELOG.md for details. For pre-releases, please refer to CHANGELOG.md of the minor branch.
Release 2026-07-18 00:30
Release 2026-07-18 00:30
- router-generator: preserve dots in virtual routes (#7845) (78dd1a645d) by @schiller-manuel
- @tanstack/react-start@1.168.30
- @tanstack/react-start-rsc@0.1.29
- @tanstack/router-cli@1.167.21
- @tanstack/router-generator@1.167.21
- @tanstack/router-plugin@1.168.22
- @tanstack/router-vite-plugin@1.167.22
- @tanstack/solid-start@1.168.30
- @tanstack/start-plugin-core@1.171.22
- @tanstack/vue-start@1.168.29
@tanstack/start-plugin-core@1.171.22
- Updated dependencies [
78dd1a6]:- @tanstack/router-generator@1.167.21
- @tanstack/router-plugin@1.168.22
@tanstack/router-plugin@1.168.22
- Updated dependencies [
78dd1a6]:- @tanstack/router-generator@1.167.21