Vite plugin
Source-accurate prompts and Tailwind detection for Vite-based React apps.
What it does#
Three things:
- Injects
data-wv-source="<file>:<line>:<col>"onto every JSX element in your project at dev-build time. The runtime reads this attribute to anchor prompts to source code. - Probes for Tailwind. If it finds
tailwind.config.{js,ts,mjs,cjs}or thetailwindcsspackage, it auto-enablestailwindVerbatimClassesfor the prompt generator. - Exposes a virtual module
virtual:weevar-configthat returns your merged config (weevar.config.json+weevar.config.js/mjs+ Tailwind probe results), so the runtime can pick it up without a separate file read.
The plugin runs in the pre phase, before @vitejs/plugin-react, so the JSX it transforms is the source you wrote, not React's output.
Install#
The plugin is bundled with the main package - no separate install.
npm install weevar
Register#
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { weevar } from "weevar/vite";
export default defineConfig({
plugins: [weevar(), react()],
});
Order matters. weevar() should come before react() so it sees the JSX before the React plugin transforms it.
What gets injected#
For every JSX opening tag (.jsx, .tsx) outside node_modules, the plugin appends an attribute like:
<NavItem data-wv-source="src/components/NavItem.tsx:12:4" />
The value is the path relative to your project root, plus the line and column where the tag begins. If a data-wv-source is already present (because you set it manually, or another plugin did), the existing one is kept.
Tailwind detection#
On startup, the plugin walks up from your project's cwd looking for:
tailwind.config.js/.ts/.mjs/.cjstailwindcsslisted inpackage.jsondependencies / devDependenciescontentglobs declared in your tailwind config
If any of those match, the merged config returned by the virtual module gets:
{
prompts: {
tailwindVerbatimClasses: true,
tailwindContentGlobs: [...], // when content globs are resolvable
tailwindConfigPath: "tailwind.config.ts",
}
}
You don't need to set anything manually. When this is active, layout prompts include verbatim class strings, and style tweak prompts include Tailwind utility suggestions alongside the raw CSS values.
Virtual config module#
The plugin resolves virtual:weevar-config (with a leading null byte internally) to a small ES module that exports your merged config as the default. The runtime imports this lazily.
If you want to read it from your own code:
import config from "virtual:weevar-config";
console.log(config.prompts);
It's a frozen JSON value; no functions are evaluated at runtime.
Config precedence#
When the plugin builds the merged config, the order is:
- Default values (none - empty object)
weevar.config.jsonif it existsweevar.config.mjsorweevar.config.jsif it exists (JS wins on overlap; deep-merged)- Tailwind probe results (only set if not already specified)
- Inline
<Weevar config={...} />props (deep-merged at runtime)
See Config file → for the schema.
Opting out of source injection#
The plugin currently has no opt-out flag for source injection. If you need it skipped for a specific file, set data-wv-source manually on the relevant elements (it won't be overwritten) or move the file to a path the plugin doesn't match (e.g. node_modules).