npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

unplugin-reactive-vue

v1.0.2

Published

Reactivity Transform on $-Prefixed Identifiers

Readme

unplugin-reactive-vue

This is an unplugin implementation of a Vue reactivity transform where local reactive variables are identified by a $ prefix. Currently, the implementation has not been battle tested and may contain fixable edge cases. If you encounter such, please open an issue or submit a pull request.

Why this is better

The original proposal was rejected partially on the grounds that losing .value where a ref was used hid the reactive nature of related operations. By instead prefixing the actual identifier its reactive nature is consistently indicated through the file, even in the template where there is already a "special case" in place that makes it so adding .value is generally not needed. In other words, projects that consistently use this transform can expect fewer sources of errors regarding the accidental omission of .value and less verbose code without hiding sources of reactivity.

Semantics

Here are some examples of what the transformed code might look like:

  • let $x = 123 -> let $x = ref(123)
  • use($x) -> use($x.value)
  • $x = 321 -> $x.value = 321
  • $x++ -> $x.value++
  • let $x = $(existingRef) binds an existing ref (e.g. from computed(...)) to a reactive variable
  • $$(...) disables the transform for an expression, allowing access to the underlying refs

Features

The transform seamlessly handles many complex reactivity scenarios out-of-the-box:

  • Destructuring declarations: let { $a } = $(useFeature()) correctly tracks $a as a reactive reference.
  • Reactive function parameters: function foo($a) { $a = 2; } automatically unwraps $a to $a.value inside the function body.
  • Imported bindings: import { $state } from './store' intelligently tracks and unwraps $state on use.

It also uses magic-string to preserve source maps.

There are some caveats:

  • Reactive variables cannot be the iteration variable in for..in or for..of loops.
  • Destructuring a reactive object (e.g. from a store) using reactive variables requires the $() macro (e.g. let { $count } = $(store)) to safely inject toRefs and maintain reactivity.
  • var is not supported and will lead to edge cases and undefined behavior if used. This allows the transform to occur in a single pass and not waste processing time for an anti-pattern.

Usage

Install in your project, e.G. pnpm install unplugin-reactive-vue, then add the plugin to your bundler configuration:

// vite.config.ts
import ReactiveVue from "unplugin-reactive-vue/vite";
import vue from "@vitejs/plugin-vue";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [ReactiveVue({}), vue()],
});

Options

export interface ReactiveVueOptions {
  include?: RegExp | RegExp[]; // Filter files to transform
  exclude?: RegExp | RegExp[]; // Filter files to not transform
  importSource?: string; // The import source for the reactivity APIs (default: 'vue')
  prefix?: string; // The prefix for reactive variables (default: '$')
  wrapCallee?: string; // The function name used to wrap an existing ref (default: '$')
  escapeCallee?: string; // The function name used to escape the transform (default: '$$')
  dts?: string; // Generate TypeScript declaration for macros (default: '').
}

TypeScript

If you are using the default settings, you can simply add the pre-packaged macro typings to your tsconfig.json:

{
  "compilerOptions": {
    "types": ["unplugin-reactive-vue/types"]
  }
}

If you customize the wrapCallee and/or escapeCallee, you can enable the dts: true option in your plugin configuration to generate a custom reactive-macros.d.ts file automatically, and add it to your tsconfig.json's includes. Alternatively, you can adapt macros-global.d.ts to your needs or add it to an existing type definitions file in your project, e.G. vite-env.d.ts.

Try it out!

This repository contains an example vue app demonstrating the basic functionality of the transform. Just poke around!

git clone https://git.ulra.eu/adro/unplugin-reactive-vue`
cd unplugin-reactive-vue
pnpm install && pnpm build
pnpm run dev # To run tests
cd example
pnpm install && pnpm run dev # To run the example with the  vite development server