Custom View Components
The peripheral panel in @swedishembedded/vemu-react is a plugin system: every
peripheral view is a React component implementing one interface, looked up from
a registry by peripheral name. The built-in inspectors (KMU, UICR) use the same
mechanism — your views are not second-class.
The view contract
A view receives everything it needs through
PeripheralViewProps:
import type { PeripheralViewProps } from "@swedishembedded/vemu-react";
export function MyTimerView({ name, events, refreshKey, getSnapshot, sendCommand }: PeripheralViewProps) {
// 1. Filter the event stream for kinds your peripheral emits.
const myEvents = events.filter((e) => e.kind.startsWith("nrf.timer."));
// 2. Pull a state snapshot whenever refreshKey bumps.
// The shape is the peripheral's snapshot field map — see its reference page.
const snapshot = getSnapshot();
// 3. Drive the peripheral with its documented commands.
const inject = () => sendCommand({ name: "inject_fault", params: { kind: "bus" } });
return <pre>{JSON.stringify(snapshot, null, 2)}</pre>;
}The pieces:
events— the recent host event envelopes ({ kind, payload }); filter by the kinds listed on your peripheral's reference page.refreshKey— a monotonic counter that bumps when new events arrive or snapshots change; depend on it inuseEffectto re-read snapshots.getSnapshot()— the peripheral's current inspector field map (documented as "snapshot fields" on its reference page).sendCommand(cmd)— sends an inspector command; names and params are documented per peripheral.
Register the view
Map a peripheral name to your component in the PERIPHERAL_VIEWS registry:
import { PERIPHERAL_VIEWS, PERIPHERAL_LABELS } from "@swedishembedded/vemu-react";
import { MyTimerView } from "./MyTimerView";
PERIPHERAL_VIEWS["timer0"] = MyTimerView;
PERIPHERAL_LABELS["timer0"] = "TIMER0";When peripheral_list() reports a peripheral named timer0, the
PeripheralPanel renders your view; unregistered peripherals fall back to the
generic JSON inspector (GenericInspector).
Discover what a peripheral supports
You never have to guess kinds, commands, or snapshot shapes:
- At design time — every published peripheral has a reference page listing
its accepted/emitted event kinds with payload schemas, commands with params,
and snapshot fields. The same data is machine-readable at
/docs/reference.json. - At runtime — the emulator describes itself; see runtime introspection.
The docs and the runtime can't disagree: peripheral metadata is declared in the emulator source and extracted from the same wasm build this site ships.