The $debug API
$debug is a global function installed by the plugin in development. This page covers how to call it and what it prints. Its runtime controls (ns, enable, disable, setLevel, setPrefixFilter) are described in Namespaces and filtering.
Call signature and payload rendering
$debug<T>(
level: 'error' | 'warning' | 'info' | 'debug' | 'success' | 'trace',
payload: string | Error | T,
options?: {
showStack?: boolean
showSource?: boolean
tag?: string
prefix?: string // override the rendered prefix for this call
inspect?: boolean // force or suppress the live browser value for this call
}
): void
// also variadic — log several values, or a printf format string:
$debug('info', label, user, el) // space-joined + each stays live
$debug('info', '%s scored %d', name, score) // printf substitution| Per-call option | Effect |
|---|---|
showStack | Append the (redacted) stack when the payload is an Error. Defaults to the plugin's showStack option. |
showSource | Show the call's original file:line:col. Defaults to the plugin's showSource option. |
tag | A label rendered in brackets after the level, e.g. [PropsValidator]. |
prefix | Replace the rendered prefix for this call, in the browser console, the dev terminal and SSR output. |
inspect | Browser only: true forces the live value, false suppresses it. Defaults to the plugin's output.inspect option. |
Set output.inspect to change the default, or pass { inspect: true | false } on one call. When a RegExp redact entry or redactDefaults is configured, no live value is handed to the console, DOM nodes included, so a secret cannot slip past redaction inside a live object. String redact entries never reach the browser, so they do not change this. inspect: true overrides it for one call: use it only on values you know hold no secrets (see Live values in the browser). The dev terminal and SSR output always receive the redacted string. An earlier development name, raw, is also accepted, with a one-time console warning, until 2.0; when both are set, inspect wins.
The table below is the one-line summary, used for the dev terminal and as the console label. In the browser, the raw value is also handed to the console, so it stays live and inspectable: see Live object inspection.
| Payload type | Summary |
|---|---|
string | as-is |
number / boolean | String(value): 42, true |
null / undefined | the literal words null / undefined |
function | name [Function] (anonymous [Function] when unnamed) |
symbol | Symbol(description) |
Error | error.message (stack appended when showStack: true; both redacted) |
| object / array | JSON.stringify with a circular guard, truncated at 500 characters after redaction |
| class instance | ClassName { … } |
Map / Set | Map(n) / Set(n) with entries |
RegExp | /pattern/flags |
Date | ISO-8601 string |
bigint | 123n |
| Vue ref | .value unwrapped, then the standard rules apply |
| DOM node | <tag#id.class> summary |
Promise | [Promise] (not awaited) |
Levels
| Level | Default label | Default CSS color | Terminal color | Browser console method | Order |
|---|---|---|---|---|---|
trace | Trace | #a855f7 | magenta | console.trace | 0 |
debug | Debug | #6b7280 | gray | console.debug | 1 |
info | Info | #3b82f6 | blue | console.info | 2 |
success | Success | #10b981 | green | console.log | 3 |
warning | Warning | #f59e0b | yellow | console.warn | 4 |
error | Error | #ef4444 | red | console.error | 5 |
minLevel keeps every level at or above the threshold (trace < debug < info < success < warning < error). To choose which levels are kept, see the levels and minLevel options; to change a label or a color, see the colors option.
Multiple values and printf
Pass more than one payload and they render like console.log(a, b, c): the summaries are space-joined on one line, and in the browser each non-primitive value stays live and inspectable:
$debug("info", "user", user, el); // "user { … } <div#app>" + live user + live nodeOr lead with a printf-style format string and its substitution arguments. Unlike native console substitution, this is done by the plugin, so it works in the browser and the terminal:
$debug("info", "%s scored %d", name, score); // "Ann scored 42"Supported specifiers: %s %o %O %j (stringify), %d %i (integer), %f (float), %c (consumed), %% (literal %). Leftover arguments are space-joined; a missing argument leaves its specifier literal. A trailing MTCallOptions-shaped object is still treated as options, so $debug("info", value, { tag: "x" }) keeps working.
With string redact entries configured, a %d, %i or %f from the browser whose number reads differently from its argument ("007" printed as 7) is masked whole in the terminal and the log file, whatever its argument; the browser console still shows the number. Pass an integer, or use %s.
Typos in the trailing object are not type errors
On the variadic form any object is a valid payload, so TypeScript cannot flag { tagg: "x" }. At run time an object counts as options only when every key is a recognized option; anything else is logged as a payload, which puts the typo in front of you instead of silently applying nothing. Use the two-argument form when you want autocompletion on options.
Utility helpers
$debug carries console-style helpers. Every one is stripped from production builds along with the base calls, including the method ($debug.time(...)) and chained ($debug.ns('x')('info')) forms.
$debug.assert(user.id != null, "user must have an id", { tag: "auth" });
// logs at "error" level ONLY when the condition is falsy
$debug.time("render");
renderExpensiveThing();
$debug.timeEnd("render"); // → MARS-TECH Debug [render] - render: 12.4ms
$debug.count("api-call"); // → api-call: 1
$debug.count("api-call"); // → api-call: 2
$debug.group("checkout"); // real collapsible group in the browser
$debug("info", "validating cart"); // nested under the group
$debug("info", "charging card");
$debug.groupEnd();
$debug.table(rows, ["name", "total"]); // console.table in the browser
$debug.dir(document.body); // console.dir deep-object inspection| Helper | Behavior |
|---|---|
assert(condition, payload, opts?) | Logs payload at error level only when condition is falsy. |
time(label?) / timeEnd(label?) | Logs the elapsed milliseconds between the two calls at debug level. The label defaults to default. |
count(label?) | Increments and logs a named counter at debug level. |
group(label?) / groupCollapsed(label?) / groupEnd() | Opens a real (optionally collapsed) console group in the browser; indents the dev-terminal output. The label is redacted like a message. |
table(data, columns?) | console.table in the browser; a text summary is sent to the terminal. With a RegExp redact entry or redactDefaults configured, the browser prints the redacted summary instead. |
dir(item, options?) | console.dir deep-object inspection in the browser; a text summary is sent to the terminal. With a RegExp redact entry or redactDefaults configured, the browser prints the redacted summary instead. |
Every helper follows the runtime switches: disable(), setLevel, the prefix filter. For time / timeEnd and count, the label doubles as the namespace, so a targeted namespace filter such as -render mutes a time("render") pair. group / groupCollapsed, table and dir carry no namespace, so they filter like a call with no tag: a -cart filter leaves them alone, while disable() or a filter that names namespaces (auth:*) hides them. Like time and count, they print only while the debug level is enabled. A filtered-out group keeps its groupEnd paired, so nesting never drifts. Timing uses performance.now() when available.
count and time remember up to 1,000 labels each. Past that, the least recently used label is forgotten: its count starts again at 1 and its timeEnd prints nothing. A label built from data (count(item.id)) therefore cannot grow memory for the life of the page. The group indent stops growing at 32 levels; groupEnd still closes every level.
Every helper above exists on every $debug: in the browser, during SSR, in the Vite process, in the Vitest no-op stub, with test: 'log', and in the shims prepended to a brandPrefix build. A call that works in a component cannot fail during server rendering or under test.