Extension guides
Typed protocols
A protocol is the single source of truth for renderer-to-host method calls and host-to-renderer events. TypeScript infers it and both processes validate it.
Define a protocol
import { defineProtocol } from "@nativepi/extension-api";
import { z } from "@nativepi/extension-api/schema";
const task = z.object({
id: z.string(),
title: z.string(),
complete: z.boolean(),
});
export const taskProtocol = defineProtocol({
methods: {
list: { result: z.array(task) },
add: {
params: z.object({ title: z.string().min(1) }),
result: task,
},
clear: { result: z.null() },
},
events: {
changed: z.array(task),
invalidated: undefined,
},
});Methods
Every method declares a result schema. Add a params schema when the method takes one argument; omit it when the method takes no arguments. Use z.null() for an action with no meaningful result so the response is still explicit JSON.
await context.channel.call("list");
await context.channel.call("add", { title: "Review diff" });
await context.channel.call("clear");A params schema whose output includes undefined makes the argument optional. Otherwise TypeScript requires exactly one argument.
Events
An event maps directly to its payload schema. Use undefined for a payload-free event. The host emits events and the renderer subscribes:
host.emit("changed", tasks);
host.emit("invalidated");
const off = context.channel.on("changed", (nextTasks) => {
setTasks(nextTasks);
});
// Call when the component unmounts.
off();Validation path
- Method parameters are validated before leaving the renderer.
- The Pi host validates parameters again before invoking a handler.
- Method results are validated in the host and again in the renderer.
- Event payloads are validated when emitted and before each listener runs.
Errors identify the method or event where invalid data originated, which is more useful than allowing a malformed value to fail later in React.
JSON-compatible values
Values may contain null, booleans, finite numbers, strings, arrays, and plain objects containing those values. Do not send class instances, functions, symbols, dates, maps, sets, binary buffers, cyclic objects,NaN, or infinities. Convert them to explicit JSON shapes.
Schema libraries
The recommended Zod export comes from @nativepi/extension-api/schema. NativePi provides that module to renderer bundles. Any synchronous object with a compatible parse(value) method and JSON-compatible output also works.
Next, implement the protocol with the host channel.