Library / SDK
vueuse/vue-demi avatar
vueuse/vue-demi

vue-demi: The Compatibility Layer That Lets One Library Serve Vue 2 and Vue 3

GitHub describes it as 🎩 Creates Universal Library for Vue 2 & 3. The repository metadata lists JavaScript as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.

3,131 stars172 forksJavaScriptMIT

At a glance

What is it?
vue-demi is a small utility that redirects imports to the correct Vue version, letting library authors support Vue 2 and 3 from a single codebase. It works, but the README says it should not be used for new projects and will be deprecated.
Who is it for?
Adopt vue-demi if you maintain an existing Vue 2 and Vue 3 compatible library that already depends on it, or if you must support Vue 2.7 and earlier with minimal code changes. Do not use it for a new library: the README explicitly warns it should not be used for new projects and will be deprecated.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Probably not. The repository last received commits 20 months ago, on January 22, 2025.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The Problem vue-demi Solves

Writing a Vue library that works on both Vue 2 and Vue 3 is painful because the two versions export different APIs. Vue 2.6 and earlier require the separate @vue/composition-api package, Vue 2.7 has Composition API built in, and Vue 3 has a completely different reactivity system. A library author would normally have to maintain two codebases or write messy conditional imports. vue-demi (French for 'half') solves this by acting as a single import point. You write `import { ref, reactive } from 'vue-demi'`, and the package redirects to the correct underlying Vue module based on the user's environment. The target audience is library authors, not application developers. If you build a Vue component library, a composable collection, or a wrapper around a charting library, vue-demi lets you ship one package that works across the major Vue versions.

How the Redirect Works

The mechanism is straightforward. When you install vue-demi, a postinstall script detects the installed Vue version and generates the appropriate exports. For Vue 2.6 and below, it exports from `vue` and `@vue/composition-api`, and it auto-installs the Composition API plugin. For Vue 2.7, it exports from `vue` because Composition API is built in. For Vue 3, it exports from `vue` but adds polyfills for Vue 2's `set` and `del` APIs. This means your library code sees a uniform API surface. The README shows that you can import `isVue2` and `isVue3` to write version-specific logic. There is also a `Vue2` export that gives access to Vue 2's global API, like `Vue2.config.ignoredElements.push('x-foo')`, without pulling in all tree-shakable modules. The `install()` function is a safe wrapper around `Vue.use(CompositionAPI)` for Vue 2, and it becomes a no-op in Vue 3. This design is simple but effective, though it does mean the package must be present at runtime, not just at build time.

Getting Started: Installation and Configuration

To use vue-demi, you add it as a dependency of your plugin. The README gives the command `npm i vue-demi` (or yarn or pnpm). You then declare `vue` and `@vue/composition-api` as peer dependencies, with `@vue/composition-api` marked optional. The recommended peer range is `vue: ^2.0.0 || >=3.0.0`. In your dev dependencies, you pick one Vue version as your working environment, say `vue: ^3.0.0`. Then you import everything from 'vue-demi' instead of 'vue'. When publishing, the postinstall script handles the redirect. There is a caveat for Vite users: you must exclude vue-demi from pre-bundling by adding `optimizeDeps: { exclude: ['vue-demi'] }` to your vite.config.js. This is a concrete configuration step that can trip up new adopters, because without it, Vite may bundle the wrong Vue version.

Switching Versions and Aliasing

The CLI provides manual control. You can run `npx vue-demi-switch 2` or `npx vue-demi-switch 3` to force a specific redirect version. This is useful when you develop the library on one Vue version but need to test against the other. You can also alias the import name. For example, `npx vue-demi-switch 2 vue2` will make vue-demi export from `vue2` instead of `vue`. The README shows the generated code: `export * from 'vue3'` and `var isVue2 = false`. This aliasing is handy for isomorphic testing. You can set up npm scripts like `test:2` and `test:3` that switch versions before running Jest, using dev dependencies like `vue2: npm:vue@2` or `vue3: npm:vue@3`. This is a practical way to run the same test suite against both Vue versions, but it adds complexity to your test pipeline. If the postinstall hook fails or you update the Vue version, you can run `npx vue-demi-fix` to re-resolve the redirect.

Limitations and When It Is the Wrong Tool

The most significant limitation is stated directly in the README: a caution notice says 'vue-demi should not be used for new projects and will be deprecated in the future.' This is a strong signal that the project is in maintenance mode. The last release was v0.14.10 in July 2024, and the repository has not been archived, but the deprecation warning means new adopters are taking on a dependency that will not evolve. Another limitation is that vue-demi only handles the Composition API surface. It does not unify the entire Vue API, such as template compilation differences or lifecycle hooks that changed names. If your library relies on version-specific behavior beyond `ref`, `reactive`, and `defineComponent`, you still need conditional logic. Also, the auto-install of @vue/composition-api in Vue 2.6 can be surprising: it modifies the global Vue constructor. If your library is used in an application that already installs the plugin, you might get double installation, although the `install()` function is meant to be a safe alternative. Finally, vue-demi is not a runtime compatibility layer for applications; it is a build-time redirect. If you need to support both Vue versions in a single bundle without a build step, this is the wrong tool.

Alternatives and Their Different Approaches

The main alternative is to write your library using the Vue 3 Composition API and provide a separate build for Vue 2, or to use a build tool like Vite's `@vitejs/plugin-vue2` to compile for both targets. Another approach is to use the `vue-demi`-style pattern manually: maintain two entry points, one for Vue 2 and one for Vue 3, and let the package manager resolve them via `exports` field or npm aliases. The difference is that vue-demi centralizes the redirect logic and handles the @vue/composition-api plugin installation automatically. A library like `@vue/composition-api` itself is not an alternative; it is a dependency that vue-demi uses. For new projects, the Vue team recommends using the Composition API with a single codebase and providing a compatibility build via `@vue/composition-api` only if you must support Vue 2.6. The key difference is that vue-demi is a runtime redirect, while a build-time dual-package approach gives you more control over the final bundle but requires more setup.

Maintenance and License

vue-demi is licensed under MIT, so you can freely use and modify it. The maintenance situation is clear: the README warns of future deprecation, and the release history shows small patch updates (v0.14.8 in May 2024, v0.14.9 and v0.14.10 in July 2024). This suggests the project is stable but not actively developed. The upgrade cost is low because the API surface is small, but you should monitor the deprecation timeline. If you rely on vue-demi, you will eventually need to migrate to a solution that the Vue ecosystem adopts post-deprecation. The postinstall script can be a source of friction in environments that disable lifecycle scripts (common in some CI setups), and you may need to run `vue-demi-fix` manually. The README does not specify a maintenance policy or a migration path, so you should verify the project's issue tracker for any announced plans before committing.

Editorial conclusion

Adopt vue-demi if you maintain an existing Vue 2 and Vue 3 compatible library that already depends on it, or if you must support Vue 2.7 and earlier with minimal code changes. Do not use it for a new library: the README explicitly warns it should not be used for new projects and will be deprecated. Before building on it, verify your target Vue versions, test the postinstall redirect on both npm and pnpm, and check whether your bundler (especially Vite) excludes vue-demi from pre-bundling. The project's last release was in July 2024, and the maintainers signal a clear sunset path, so plan a migration to native dual-version support or a fork if you need long-term compatibility.

Official sources

  1. Official README
  2. Project repository
  3. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/vueuse-vue-demi.svg)](https://hysenlabs.com/projects/vueuse-vue-demi)