---
title: "VueUse 14: Vue 3.5 minimum, deprecated aliases and a sync computedAsync · vuejs.school"
description: "VueUse 14.0 requires Vue 3.5, marks the old alias names deprecated, changes computedAsync and useThrottleFn timing, and moves its build to tsdown."
canonical_url: "https://vuejs.school/community/blog/vueuse-14-vue-3-5-minimum"
meta:
  "og:description": "VueUse 14.0 requires Vue 3.5, marks the old alias names deprecated, changes computedAsync and useThrottleFn timing, and moves its build to tsdown."
  "og:image": "https://vuejs.school/_og/d/a_~VnVlVXNlIDE0OiBWdWUgMy41IG1pbmltdW0sIGRlcHJlY2F0ZWQgYWxpYXNlcyBhbmQgYSBzeW5jIGNvbXB1dGVkQXN5bmMgwrcgdnVlanMuc2Nob29s%2Cc_OgCard.takumi%2Ctitle_~VnVlVXNlIDE0OiBWdWUgMy41IG1pbmltdW0sIGRlcHJlY2F0ZWQgYWxpYXNlcyBhbmQgYSBzeW5jIGNvbXB1dGVkQXN5bmM%2Cdescription_~VnVlVXNlIDE0LjAgcmVxdWlyZXMgVnVlIDMuNSwgbWFya3MgdGhlIG9sZCBhbGlhcyBuYW1lcyBkZXByZWNhdGVkLCBjaGFuZ2VzIGNvbXB1dGVkQXN5bmMgYW5kIHVzZVRocm90dGxlRm4gdGltaW5nLCBhbmQgbW92ZXMgaXRzIGJ1aWxkIHRvIHRzZG93bi4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA3IG1pbiByZWFk%2Ctint_sand%2Cp_Ii9jb21tdW5pdHkvYmxvZy92dWV1c2UtMTQtdnVlLTMtNS1taW5pbXVtIg%2Cs_RB_shkqdJBQuoZc_.png"
  "og:image:alt": "VueUse 14: Vue 3.5 minimum, deprecated aliases and a sync computedAsync · vuejs.school"
  "og:image:height": "600"
  "og:image:type": image/png
  "og:image:width": "1200"
  "og:title": "VueUse 14: Vue 3.5 minimum, deprecated aliases and a sync computedAsync · vuejs.school"
  "twitter:image": "https://vuejs.school/_og/d/a_~VnVlVXNlIDE0OiBWdWUgMy41IG1pbmltdW0sIGRlcHJlY2F0ZWQgYWxpYXNlcyBhbmQgYSBzeW5jIGNvbXB1dGVkQXN5bmMgwrcgdnVlanMuc2Nob29s%2Cc_OgCard.takumi%2Ctitle_~VnVlVXNlIDE0OiBWdWUgMy41IG1pbmltdW0sIGRlcHJlY2F0ZWQgYWxpYXNlcyBhbmQgYSBzeW5jIGNvbXB1dGVkQXN5bmM%2Cdescription_~VnVlVXNlIDE0LjAgcmVxdWlyZXMgVnVlIDMuNSwgbWFya3MgdGhlIG9sZCBhbGlhcyBuYW1lcyBkZXByZWNhdGVkLCBjaGFuZ2VzIGNvbXB1dGVkQXN5bmMgYW5kIHVzZVRocm90dGxlRm4gdGltaW5nLCBhbmQgbW92ZXMgaXRzIGJ1aWxkIHRvIHRzZG93bi4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA3IG1pbiByZWFk%2Ctint_sand%2Cp_Ii9jb21tdW5pdHkvYmxvZy92dWV1c2UtMTQtdnVlLTMtNS1taW5pbXVtIg%2Cs_RB_shkqdJBQuoZc_.png"
  "twitter:image:alt": "VueUse 14: Vue 3.5 minimum, deprecated aliases and a sync computedAsync · vuejs.school"
---

> Index of every page on this site: [llms.txt](https://vuejs.school/llms.txt)

## The twelve breaking changes

The release notes list these under the breaking heading:

- VueUse now requires Vue 3.5.
- The alias exports are deprecated in favour of the original function names.
- The build moved to `tsdown`, and the dist files moved.
- `computedAsync` defaults to `flush: 'sync'`.
- `createSharedComposable` returns the shared composable only on the client.
- `useThrottleFn` is aligned with traditional throttle behaviour.
- The components in `@vueuse/components` were refactored to be consistent.
- `@vueuse/shared` drops some deprecated APIs.
- `useClipboard` uses `readonly()` instead of a type assertion.
- `useSwipe` loses `isPassiveEventSupported`.
- `@vueuse/firebase` moves to Firebase 12.
- `@vueuse/nuxt` uses the Nuxt 4 kit (its peer range still accepts Nuxt 3).

Outside that heading, the notes deprecate two functions outright, `computedEager` and `watchPausable` (more on both below), and add a few things:

- `refManualReset`, a new function.
- `onClickOutside` accepts a getter as its `target`.
- `onLongPress` accepts a function as its `delay`.
- `useAsyncState` accepts a ref as its initial value.
- `watchAtMost` returns `pause` and `resume`.

One fix is worth knowing too: `useAsyncState` now tracks the latest execution, so a slow earlier call can no longer overwrite the result of a faster later one.

## Vue 3.5 is the floor

VueUse 13 already listed `vue@^3.5.0` as its peer dependency, and 3.5 has been Vue's current minor since September 2024, so for most projects this changes nothing. Check with `npm ls vue`. If it prints 3.4 or lower, upgrade Vue first with `npm install vue@^3.5`.

Five deprecated exports are also gone from `@vueuse/shared`, and so from `@vueuse/core`, which re-exports it: `toValue`, `resolveRef`, `resolveUnref`, `MaybeRef` and `MaybeRefOrGetter`. Vue has shipped `toValue`, `MaybeRef` and `MaybeRefOrGetter` itself since 3.3, so the fix is an import change:

*composables/useGreeting.ts**Breaks***

```
import { toValue, type MaybeRefOrGetter } from '@vueuse/shared'
```

*composables/useGreeting.ts**Works***

```
import { toValue, type MaybeRefOrGetter } from 'vue'
```

`resolveRef` and `resolveUnref` were the old names for `toRef` and `toValue`; both also come from `vue`.

## The deprecated aliases and how to find them

Years ago VueUse renamed a group of functions so that each name starts with what the function returns or wraps: `ref…`, `watch…`, `computed…`. The old names stayed as aliases. Version 14 marks every one of them `@deprecated`. They still work, your editor strikes them through, and they are marked for removal in a future release.

The pairs, old name first:

- Computeds: `asyncComputed` → `computedAsync`, `eagerComputed` → `computedEager`, `controlledComputed` → `computedWithControl`.
- Refs: `autoResetRef` → `refAutoReset`, `debouncedRef` and `useDebounce` → `refDebounced`, `throttledRef` and `useThrottle` → `refThrottled`, `controlledRef` → `refWithControl`.
- Watchers: `debouncedWatch` → `watchDebounced`, `ignorableWatch` → `watchIgnorable`, `pausableWatch` → `watchPausable`, `throttledWatch` → `watchThrottled`.
- Others: `createReactiveFn` → `reactify`; the directives `VOnClickOutside` → `vOnClickOutside` and `VOnLongPress` → `vOnLongPress`; and in `@vueuse/math`, `and`, `or` and `not` → `logicAnd`, `logicOr` and `logicNot`.

Run this from the project root to list every use in `src` (in a Nuxt 4 project, search `app` instead). The `\b` around the names keeps `useDebounceFn` and `useThrottleFn`, which are not deprecated, out of the results:

```
grep -rnE "\b(asyncComputed|eagerComputed|controlledComputed|createReactiveFn|autoResetRef|debouncedRef|useDebounce|throttledRef|useThrottle|controlledRef|debouncedWatch|ignorableWatch|pausableWatch|throttledWatch|VOnClickOutside|VOnLongPress)\b" src
```

The three math aliases are too short to grep for safely; open the files that import from `@vueuse/math` and read them.

Two of the replacement names are themselves deprecated in this release: `watchPausable`, because the `watch` in Vue 3.5 already returns `pause` and `resume` on its handle, and `computedEager`, because Vue's own `computed` has not re-triggered effects for an unchanged value since 3.4. Replace `pausableWatch` and `watchPausable` with a plain `watch` (its handle has no `isActive`, so keep your own flag if you read it), and `eagerComputed` and `computedEager` with `computed`.

## `computedAsync` now runs on every change

`computedAsync` is a computed whose evaluation function returns a promise. Under the hood it is a watcher, and the `flush` option of that watcher decides when the function runs after a dependency changes. The default used to be `pre`, which batches the changes made in one tick and runs once before the next render. In 14 the default is `sync`: the function runs the moment a dependency changes.

When changes arrive one at a time, as when someone types into a search field, you will not see a difference. When several land in the same tick, say a button that resets both the query and the category, 14 starts one evaluation per change. Only the last result is kept, but if each evaluation sends a network request, you now send more of them.

Pass the old value to keep the old behaviour. Here `query` and `category` are refs, and `searchProducts` is your own function that calls the API:

```
import { computedAsync } from '@vueuse/core'

const results = computedAsync(
  () => searchProducts(query.value, category.value),
  [],
  { flush: 'pre' },
)
```

The [pull request](https://github.com/vueuse/vueuse/pull/4752) gives consistency as the reason: VueUse's other watcher-based computeds, `computedEager` and `computedWithControl`, already used `sync`. Decide per call site. For a derived value that is cheap to compute, `sync` is fine and more predictable. For a request, add `flush: 'pre'`.

## `createSharedComposable` stops sharing on the server

`createSharedComposable` wraps a composable so that every component calling it shares one instance of the state, and tears that state down when the last component leaves. On the client that is unchanged.

On the server, where one Node process renders requests for many users, 14 returns the original, unshared composable instead. Shared state in a server process would be shared between requests, and one visitor's data could leak into another's page. VueUse decides by checking whether `window` and `document` exist, so a Vitest test in the default `node` environment also gets the unshared version.

If a Nuxt app relied on two components seeing the same instance during server rendering, they no longer do; move that state into `useState` or a Pinia store.

## `useThrottleFn` with `leading: false` skips the first call

`useThrottleFn(fn, ms, trailing, leading)` returns a function that runs `fn` at most once per `ms`. The defaults (`trailing: false`, `leading: true`) behave as before; only calls that pass `leading: false` change.

In 13, `leading: false` did not reliably hold back the first run, because VueUse counted the interval only from runs that actually happened. With `trailing: true`, the first call of a burst still ran straight away; without it, the second call did. In 14 a call that is held back starts the interval too, and the [pull request](https://github.com/vueuse/vueuse/pull/4923) says this brings `useThrottleFn` closer to `lodash.throttle`. A burst now gets its first run one interval after it starts, then one per interval. If you had added a guard because `leading: false` still fired at the start, remove it.

A call on its own is now dropped too, even with `trailing: true`. A single click through `useThrottleFn(save, 1000, true, false)` ran `save` in 13 and does nothing in 14, because only a second call within the interval schedules a run. For something a user triggers once, keep the default `leading: true`.

## Deep file imports and the components package

The packages are now built with `tsdown`, and the output lives in a `dist/` folder: the main entry moved from `./index.mjs` to `./dist/index.js`. An `import { useMouse } from '@vueuse/core'` is unaffected. A deep import of a file path, such as `@vueuse/core/index.mjs`, breaks; replace it with the package import.

`@vueuse/components` keeps every component name, but the refactor reworks their props, emits and slot types, and the package's own imports now point at `@vueuse/core`. The [pull request](https://github.com/vueuse/vueuse/pull/4912) says usage will differ somewhat, so check the documentation page of each `<Use…>` component you render.

## How to upgrade

Install the new majors together, keeping only the packages your project already uses:

```
npm install @vueuse/core@14 @vueuse/components@14 @vueuse/integrations@14 @vueuse/math@14 @vueuse/nuxt@14
```

Then check your code in three passes:

1. Run `npx vue-tsc --noEmit`. The removed exports from `@vueuse/shared` show up as type errors with the file and line.
2. Run the grep above and rename the aliases while you are in the files.
3. Search for `computedAsync(`, `createSharedComposable(` and `useThrottleFn(`, and check each call against the sections above.

**Check it stuck**3 questions from the Meet VueUse quiz.

[**Practice now**](https://vuejs.school/learn/vueuse/meet-vueuse?tab=quiz)

**Was this helpful?**

## **Keep reading**

[Deep dive · 6 min read**VueUse 15's new composables: useWebMCP, useLiveAnnouncer and useTemporalNow**](https://vuejs.school/community/blog/vueuse-15s-new-composables-usewebmcp-useliveannouncer-usetemporalnow) [Release notes · 6 min read**VueUse 15: the breaking changes in plain words**](https://vuejs.school/community/blog/vueuse-15-the-breaking-changes-in-plain-words)

```json
{"@context":"https://schema.org","@graph":[{"@id":"https://vuejs.school/#website","@type":"WebSite","description":"A free AI-instructed school for Vue.js. Short tutorials, runnable code and quizzes that adapt to you.","name":"vuejs.school","url":"https://vuejs.school/","publisher":{"@id":"https://vuejs.school/#identity"}},{"@id":"https://vuejs.school/community/blog/vueuse-14-vue-3-5-minimum#webpage","@type":"WebPage","dateModified":"2026-10-27T19:31:40.253Z","datePublished":"2025-10-28","description":"VueUse 14.0 requires Vue 3.5, marks the old alias names deprecated, changes computedAsync and useThrottleFn timing, and moves its build to tsdown.","name":"VueUse 14: Vue 3.5 minimum, deprecated aliases and a sync computedAsync","url":"https://vuejs.school/community/blog/vueuse-14-vue-3-5-minimum","breadcrumb":{"@id":"https://vuejs.school/community/blog/vueuse-14-vue-3-5-minimum#breadcrumb"},"isPartOf":{"@id":"https://vuejs.school/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://vuejs.school/community/blog/vueuse-14-vue-3-5-minimum"]}],"primaryImageOfPage":{"@id":"https://vuejs.school/#logo"}},{"@id":"https://vuejs.school/#identity","@type":"Organization","description":"A free AI-instructed school for Vue.js. Short tutorials, runnable code and quizzes that adapt to you.","name":"vuejs.school","url":"https://vuejs.school","logo":{"@id":"https://vuejs.school/#logo"}},{"@id":"https://vuejs.school/community/blog/vueuse-14-vue-3-5-minimum#article","dateModified":"2026-10-27T19:31:40.253Z","datePublished":"2025-10-28","description":"VueUse 14.0 requires Vue 3.5, marks the old alias names deprecated, changes computedAsync and useThrottleFn timing, and moves its build to tsdown.","headline":"VueUse 14: Vue 3.5 minimum, deprecated aliases and a sync computedAsync","inLanguage":"en","isAccessibleForFree":true,"thumbnailUrl":"https://vuejs.school/_og/d/a_~VnVlVXNlIDE0OiBWdWUgMy41IG1pbmltdW0sIGRlcHJlY2F0ZWQgYWxpYXNlcyBhbmQgYSBzeW5jIGNvbXB1dGVkQXN5bmMgwrcgdnVlanMuc2Nob29s%2Cc_OgCard.takumi%2Ctitle_~VnVlVXNlIDE0OiBWdWUgMy41IG1pbmltdW0sIGRlcHJlY2F0ZWQgYWxpYXNlcyBhbmQgYSBzeW5jIGNvbXB1dGVkQXN5bmM%2Cdescription_~VnVlVXNlIDE0LjAgcmVxdWlyZXMgVnVlIDMuNSwgbWFya3MgdGhlIG9sZCBhbGlhcyBuYW1lcyBkZXByZWNhdGVkLCBjaGFuZ2VzIGNvbXB1dGVkQXN5bmMgYW5kIHVzZVRocm90dGxlRm4gdGltaW5nLCBhbmQgbW92ZXMgaXRzIGJ1aWxkIHRvIHRzZG93bi4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA3IG1pbiByZWFk%2Ctint_sand%2Cp_Ii9jb21tdW5pdHkvYmxvZy92dWV1c2UtMTQtdnVlLTMtNS1taW5pbXVtIg%2Cs_RB_shkqdJBQuoZc_.png","@type":["Article","BlogPosting"],"articleSection":["Release notes"],"author":{"@id":"https://vuejs.school/#identity"},"image":{"@id":"https://vuejs.school/#/schema/image/1"},"isPartOf":{"@id":"https://vuejs.school/community/blog/vueuse-14-vue-3-5-minimum#webpage"},"mainEntityOfPage":{"@id":"https://vuejs.school/community/blog/vueuse-14-vue-3-5-minimum#webpage"},"publisher":{"@id":"https://vuejs.school/#identity"}},{"@id":"https://vuejs.school/community/blog/vueuse-14-vue-3-5-minimum#breadcrumb","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","name":"Blog","item":"https://vuejs.school/community/blog","position":1},{"@type":"ListItem","name":"VueUse 14: Vue 3.5 minimum, deprecated aliases and a sync computedAsync","position":2}]},{"@id":"https://vuejs.school/#logo","@type":"ImageObject","caption":"vuejs.school","contentUrl":"https://vuejs.school/apple-touch-icon.png","inLanguage":"en","url":"https://vuejs.school/apple-touch-icon.png"},{"@id":"https://vuejs.school/#/schema/image/1","@type":"ImageObject","contentUrl":"https://vuejs.school/_og/d/a_~VnVlVXNlIDE0OiBWdWUgMy41IG1pbmltdW0sIGRlcHJlY2F0ZWQgYWxpYXNlcyBhbmQgYSBzeW5jIGNvbXB1dGVkQXN5bmMgwrcgdnVlanMuc2Nob29s%2Cc_OgCard.takumi%2Ctitle_~VnVlVXNlIDE0OiBWdWUgMy41IG1pbmltdW0sIGRlcHJlY2F0ZWQgYWxpYXNlcyBhbmQgYSBzeW5jIGNvbXB1dGVkQXN5bmM%2Cdescription_~VnVlVXNlIDE0LjAgcmVxdWlyZXMgVnVlIDMuNSwgbWFya3MgdGhlIG9sZCBhbGlhcyBuYW1lcyBkZXByZWNhdGVkLCBjaGFuZ2VzIGNvbXB1dGVkQXN5bmMgYW5kIHVzZVRocm90dGxlRm4gdGltaW5nLCBhbmQgbW92ZXMgaXRzIGJ1aWxkIHRvIHRzZG93bi4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA3IG1pbiByZWFk%2Ctint_sand%2Cp_Ii9jb21tdW5pdHkvYmxvZy92dWV1c2UtMTQtdnVlLTMtNS1taW5pbXVtIg%2Cs_RB_shkqdJBQuoZc_.png","inLanguage":"en","url":"https://vuejs.school/_og/d/a_~VnVlVXNlIDE0OiBWdWUgMy41IG1pbmltdW0sIGRlcHJlY2F0ZWQgYWxpYXNlcyBhbmQgYSBzeW5jIGNvbXB1dGVkQXN5bmMgwrcgdnVlanMuc2Nob29s%2Cc_OgCard.takumi%2Ctitle_~VnVlVXNlIDE0OiBWdWUgMy41IG1pbmltdW0sIGRlcHJlY2F0ZWQgYWxpYXNlcyBhbmQgYSBzeW5jIGNvbXB1dGVkQXN5bmM%2Cdescription_~VnVlVXNlIDE0LjAgcmVxdWlyZXMgVnVlIDMuNSwgbWFya3MgdGhlIG9sZCBhbGlhcyBuYW1lcyBkZXByZWNhdGVkLCBjaGFuZ2VzIGNvbXB1dGVkQXN5bmMgYW5kIHVzZVRocm90dGxlRm4gdGltaW5nLCBhbmQgbW92ZXMgaXRzIGJ1aWxkIHRvIHRzZG93bi4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA3IG1pbiByZWFk%2Ctint_sand%2Cp_Ii9jb21tdW5pdHkvYmxvZy92dWV1c2UtMTQtdnVlLTMtNS1taW5pbXVtIg%2Cs_RB_shkqdJBQuoZc_.png"}]}
```