Skip to content

Quickstart

Requirements

StackVersions tested
Vite6.x · 7.x · 8.x
Node.js20.19 · 22.12 · 24 (24 recommended; 20 is past end of life)
Vue3.5+ (Composition + Options API, Pinia, Vue Router)
React18+ (Redux Toolkit, React Router)
Angular20+ via Analog (NgRx, Angular Router)
Nuxt4.x (Pinia, route middleware)
SSR enginesVite 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

bash
npm install -D @mars-tech/vite-debug-plugin

Register it in vite.config.ts:

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):

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:

js
// 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 setupImport
Flat config (ESLint 9 & 10)the default export, spread as above
Custom globalNamemtDebugFlatConfig({ 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

ts
$debug("warning", new Error('Invalid variant "danger"'), {
  tag: "PropsValidator",
});

Output (both browser console and Vite terminal):

text
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.