Skip to content

Debugging

StemJSON includes a reserved context key — _debug — that requests runtime inspection output from the rendering tool. It is a language-level construct: the key and its accepted values are part of this specification; how the output is surfaced (console, log stream, dev overlay) is implementation-defined.

_debug is a development-only key. Conforming rendering tools MUST NOT emit debug output in production builds. How a tool distinguishes development from production mode is outside the scope of this specification; refer to your rendering tool’s documentation.

Attach _debug to any component’s context to request inspection of that component at runtime.

{ "id": "login_btn", "type": "button",
"context": { "_label": "Sign In", "_debug": "context" } }

_debug accepts two forms:

"_debug": "<area>"
ValueWhat is inspectedWhen
"context"The component’s fully resolved context dictionary.Every render.
"events"The component’s event map, plus each event as it is triggered or sent.Every render, and on each event fire.
"style"The component’s fully resolved style dictionary.Every render.

Dictionary form — targeted path inspection

Section titled “Dictionary form — targeted path inspection”
"_debug": { "<area>": "<path>" }

Narrows inspection to a specific key path within the area. Only one area can be active per component at a time.

ExampleWhat is inspected
{ "context": "_title" }The resolved value of _title in the component’s context.
{ "events": "onChange.actions" }The actions array inside the onChange event.
{ "style": "common.opacity" }The resolved opacity value in style.common.

Paths use the same dot-and-bracket notation as expressions (see §8.1). If a path does not resolve (key absent or type mismatch), no output is produced for that cycle.

All inspected values are shown in their fully resolved form: state references, expressions, and source strings are evaluated before the value is reported.

Inspects the values the component reads to render itself. Use this area to verify that state references and expressions produce the values you expect.

{ "id": "price_label", "type": "text",
"context": {
"_title": "{{ formatCurrency(${cart.total}) }}",
"_debug": { "context": "_title" }
}
}

Inspects the event map and traces each event as it fires and as actions are dispatched downstream. Use this area to follow an action chain and verify that payloads are forwarded correctly between steps.

{ "id": "submit_btn", "type": "button",
"context": { "_label": "Submit", "_debug": "events" }
}

Inspects the computed style dictionary. Use this area when a component renders with unexpected visual properties — for example when a conditional style expression may not be resolving as intended.

{ "id": "overlay", "type": "color",
"context": { "_debug": { "style": "common.opacity" } },
"style": { "common": { "opacity": "{{ ${loading} ? 0.4 : 1.0 }}" } }
}

Start broad, then narrow. Begin with the string form to see the full area, then switch to the dictionary form once you know which key or path to watch.

Trace action chains with events. When a chain produces an unexpected result, add "_debug": "events" to the component that fires the first action. Each dispatch step will be reported, making it straightforward to identify where the chain deviates.

Remove _debug keys before delivering to production. The key is part of the JSON payload. Even if the rendering tool suppresses output in production mode, retaining the key adds noise and signals that a payload was not cleaned up. Treat a _debug key in a production payload as a mistake.

One area per component. Only one area can be active at a time. To inspect two areas on the same component simultaneously, temporarily split it into two components.