Quickstart
Requirements
| Stack | Versions tested |
|---|---|
| Vite | 6.x · 7.x · 8.x |
| Node.js | 20.19 · 22.12 · 24 (24 recommended; 20 is past end of life) |
| Vue | 3.5+ (Composition + Options API, Pinia, Vue Router) |
| React | 18+ (Redux Toolkit, React Router) |
| Angular | 20+ via Analog (NgRx, Angular Router) |
| Nuxt | 4.x (Pinia, route middleware) |
| SSR engines | Vite SSR, Analog, Nitro/Nuxt, vite-node |
See Framework recipes for where to register the plugin in each stack, and an idiomatic call site.
1. Install and register the plugin
npm install -D @mars-tech/vite-debug-pluginRegister it in vite.config.ts:
// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import mtDebug from "@mars-tech/vite-debug-plugin";
export default defineConfig({
plugins: [vue(), mtDebug()],
});The default export is the plugin factory. It works identically with import (ESM) and require() (CommonJS). It takes no arguments by default; every knob is in Plugin options.
Register mtDebug() unconditionally
Keep it in the top-level plugins array. The plugin is not only dev tooling: during vite build, it is what strips the $debug calls. Do not gate it on the command or mode (command === "serve" && mtDebug()) and do not set apply: "serve": the build would then ship every call as written, and each one would throw in production. To turn the dev runtime off, use enabled: false, which still strips. Under build.rollupOptions.plugins, or in a Rollup or Rolldown config, the plugin only strips and installs no runtime.
2. Enable the $debug global type
Add a triple-slash reference where your project's ambient types live (commonly src/vite-env.d.ts):
/// <reference types="@mars-tech/vite-debug-plugin/client" />Module resolution
Module resolution must read the package exports map (moduleResolution: "bundler", "node16", or "nodenext"). On legacy "node10" / "classic", the package also ships a root-level client.d.ts that resolves by path, so no change is needed.
3. Tell ESLint about the global
TypeScript now knows $debug, but ESLint's no-undef rule doesn't read TS types: it will report '$debug' is not defined. Spread the shipped flat config to declare the global:
// eslint.config.js (flat config, ESLint 9 & 10)
import mtDebug from "@mars-tech/vite-debug-plugin/eslint";
export default [
mtDebug, // declares $debug as a readonly global
// ...your other configs
];The /eslint export bundles no eslint dependency, so it never pins your version: the same import works on ESLint 9 and 10.
| Your setup | Import |
|---|---|
| Flat config (ESLint 9 & 10) | the default export, spread as above |
Custom globalName | mtDebugFlatConfig({ globalName: "$log" }) |
.eslintrc (ESLint ≤9 only) | { globals: mtDebugGlobals() } (the eslintrc system was removed in v10) |
TypeScript projects
TypeScript users can instead disable no-undef for .ts files: tsc already catches undefined names.
4. Call $debug in dev code
$debug("warning", new Error('Invalid variant "danger"'), {
tag: "PropsValidator",
});Output (both browser console and Vite terminal):
MARS-TECH Warning [PropsValidator] - Invalid variant "danger" (src/components/MyButton.vue:12:6)MARS-TECH is the default prefix, Warning the label of the level, PropsValidator the tag, and the trailing (file:line:col) is the call's original source location (turn it off with showSource: false). See the $debug API for every call form, and How it works for a step-by-step demo.