Vue 3.6 RC Finishes Vapor Mode, and Nuxt 3 Has Twelve Days Left
Vue 3.6 RC completes Vapor Mode, Nuxt 4.5 moves to Vite 8 with experimental SSR streaming, and Nuxt 3 reaches end-of-life on July 31. Here is what I would check first.
Umut Korkmaz
Published: 4 min read
On this page7
Two releases landed on July 18 that Vue teams should read closely. Vue published v3.6.0-rc.1, which the team says completes the intended feature set for Vapor Mode, and Nuxt shipped v4.5.0 on Vite 8 with an experimental SSR streaming mode. The Nuxt notes also carry a date that matters more than either feature: Nuxt 3 reaches end-of-life on July 31, 2026.
What Vue 3.6 RC actually ships
There are two separate things in 3.6. The first is a major refactor of @vue/reactivity built on alien-signals, which the release notes say significantly improves the reactivity system's performance and memory usage.
The second is Vapor Mode, a new compilation mode for single-file components aimed at a smaller baseline bundle and better performance. It is 100% opt-in, and you opt in per component:
<script setup vapor>
// template-only SFCs and <script setup> are supported; Options API is not
</script>
An app built entirely from Vapor components can start with createVaporApp() and skip the Virtual DOM runtime altogether. An existing app created with createApp() installs vaporInteropPlugin to mix the two. The team says Vapor has matched Solid and Svelte 5 in third-party benchmarks, but its current recommendation is modest: a performance-sensitive page inside an existing app, or a small new app written entirely in Vapor.
The fine print before anyone adds vapor
Vapor supports a subset of Vue by design. Anything that depends on VNodes or the component public instance proxy is out. The release notes list:
- Options API and
app.config.globalProperties getCurrentInstance(), which returnsnullin Vapor componentsv-memoand@vue:xxxper-element lifecycle events$el,$props,$attrs,$slotsand$refson component template refs
Three behavioral differences are more likely to bite than the missing APIs. Vapor delegates eligible events to document, so if an ancestor calls stopPropagation(), the delegated handler never runs. Calling slots.default() to inspect slot content is not a safe dry run in Vapor; it runs the slot's rendering logic, which may create DOM, register effects, and claim SSR DOM during hydration. Custom directives get a new function-based interface. Components written with render functions or JSX stay VDOM components, and the team warns that VDOM-based component libraries may still have rough edges inside Vapor. Their advice is distinct regions per rendering mode, not mixed nesting.
Two answers to the same question
My daily stack is React and Next.js, so I read this against the React Compiler. Its docs describe a stable, build-time tool that automatically applies memoization so components only re-render when necessary, with rollout depending on how well a codebase follows the Rules of React. As I read it, React keeps its component model and the compiler decides what work to skip. Vue is making a different bet: keep the authoring model, but let the compiler emit a different kind of output per component, paying for it with a smaller API surface.
That difference shapes the team decision. React Compiler adoption is mostly a codebase-hygiene question you roll out incrementally. Vapor is an architecture question: which pages are hot enough to justify a rendering-mode boundary, and can those components live without the features above.
Nuxt 4.5: a new build layer and a streaming switch
Nuxt 4.5 moves to Vite 8 and its Rolldown-powered internals, upgrades the Rspack builder to Rspack 2 and rebuilds it on @rsbuild/core, and adopts unhead v3 and unctx v3. The notes flag three things to check: custom Vite plugins and config, custom Rspack config, and possible breaking type changes from stricter useHead typing.
The feature I would test first is experimental.ssrStreaming. Nuxt flushes the HTML shell immediately and streams the body as Vue renders it. The catch is spelled out: status and headers commit with the first byte, so a setResponseStatus() in <script setup> or a cookie write during middleware cannot reach the client. Routes with redirect, cache, isr, swr, noScripts or ssr: false rules fall back to buffered rendering, bots get fully rendered HTML, and development logs a warning naming dropped mutations. It is off by default.
Nuxt 3 has twelve days left
End-of-life is July 31. Alongside 4.5.0 the team published v3.21.9 with compatible fixes backported, but Vite 8, Rspack 2 and the unhead/unctx majors stay v4-only. If a Nuxt 3 app sits on your roadmap under "later", later now has a date.
What I'd put on the list for Monday
- Nuxt 3 apps: take the patch with
npx nuxt@latest upgrade --dedupe --channel=v3, then schedule the v4 move as its own piece of work. Do not fold it into the 4.5 major bumps in one PR. - Nuxt 4 apps: inventory custom Vite plugins before taking 4.5, and use
npx nuxt upgrade --dedupeso the unjs dependencies move together. - Streaming: search for
setResponseStatusand cookie writes in middleware before enabling it anywhere, and start with a content route. - Vapor: pick one hot page and run a rough pre-flight on it:
rg -n "getCurrentInstance|globalProperties|v-memo|@vue:|stopPropagation|slots\.default\(" src/
It is still a release candidate, so I would keep Vapor on a branch with measurements attached rather than in production. I am working through the certificates.dev Vue and Nuxt tracks right now, and this is the first Vue change in a while that makes me want to measure instead of just read.
Sources
Primary references used for this post.