DevTools Decorators
Developer experience decorators — @Debug to expose signals, computed values, and methods in DevTools, and @Trace to instrument component performance.
DevTools Decorators
Decorators that feed data into the DevTools panel. Both are no-ops unless DevTools.init() has been called — so they're safe to leave in production code with zero runtime cost.
Install:
npm install @praxisjs/devtoolspnpm add @praxisjs/devtoolsyarn add @praxisjs/devtoolsbun add @praxisjs/devtoolsimport { Debug, Trace } from '@praxisjs/devtools'@Debug(options?)
Exposes a field, getter, or method in the DevTools panel. What it tracks depends on what it decorates:
On @State() fields
Records every value change in the Signals panel with a 20-entry history. This is the most common use case.
import { Component, State } from '@praxisjs/decorators'
import { Debug } from '@praxisjs/devtools'
import { StatefulComponent } from '@praxisjs/core'
@Component()
class CartStore extends StatefulComponent {
@Debug({ label: 'Cart Items' })
@State()
items: Product[] = []
@Debug()
@State()
total = 0
}Decorator order
@Debug must be written above @State(). Decorators apply bottom-up, so @State runs first to set up the reactive accessor, then @Debug wraps it to observe changes.
On getters
Tracks a computed value by creating an internal computed() that observes the getter. Changes appear in the Signals panel.
@Debug({ label: 'Has Discount?' })
get hasDiscount() {
return this.total > 100
}On methods
Records every method call in the Timeline with arguments, return value, and execution duration in milliseconds.
@Debug()
async fetchProducts() {
this.items = await api.getProducts()
}Options:
| Option | Type | Description |
|---|---|---|
label | string | Name shown in the panel. Defaults to the field or method name. |
@Trace()
Instruments a component class to report lifecycle events and render metrics to the Components panel.
@Trace()
@Component()
class DataGrid extends StatefulComponent {
@State() rows: Row[] = []
render() {
return <table>{/* ... */}</table>
}
}Automatically tracks: onBeforeMount, onMount, onBeforeUpdate, onUpdate, onAfterUpdate, onUnmount.
The Components panel shows:
- Render count and last render duration in ms
- Mount and unmount timestamps
- Full lifecycle hook history
Decorator order
@Trace() must be written above @Component() since decorators apply bottom-up.
Production safety
@Debug and @Trace check whether DevTools.init() has been called before doing anything. If it hasn't — which is the case in every production build — they're completely inert. Use a dynamic import to ensure the DevTools package is never bundled into production at all:
// src/main.ts
import { render } from '@praxisjs/runtime'
import { App } from './app'
render(() => <App />, document.getElementById('app')!)
if (import.meta.env.DEV) {
const { DevTools } = await import('@praxisjs/devtools')
DevTools.init()
}→ See DevTools for the full setup guide and panel reference.