Skip to content

Extension guides

Graphical extension API

Add React interfaces to a Pi package without changing the package's agent behavior or its compatibility with Pi's terminal interface.

One package, two entries

A graphical package keeps its ordinary Pi extension and optional NativePi renderer separate. Pi owns tools, commands, events, state, session entries, and agent behavior. The browser renderer owns only the visual contributions NativePi mounts.

Pi process                         NativePi window
src/extension.ts                  src/renderer.tsx
      │                                 │
      └── connect(protocol) ◄───────────┤ context.channel.call()
              │                         │
              └── host.emit() ─────────►┤ context.channel.on()

When to use the API

Use a graphical renderer when a Pi capability benefits from:

  • A custom tool or session-entry presentation in the transcript
  • Compact state beside or around the composer
  • A project-scoped panel for information the reader consults
  • NativePi settings controls backed by extension-owned state

Do not use it to add model-facing logic, replace the composer or transcript, make independent LLM requests, or reproduce a Pi feature.

Contract and runtime

  • The package is @nativepi/extension-api.
  • Renderers declare the literal apiVersion: 1.
  • React ^18.3.1 || ^19.0.0 is supported and supplied by NativePi.
  • Cross-process values must be JSON-compatible and validated by synchronous schemas.
  • Renderer calls have a thirty-second timeout and reject if the active chat changes.

Recommended path

  1. Follow Build your first renderer.
  2. Read Package structure before adding runtime dependencies.
  3. Add communication with Typed protocols and the Host channel.
  4. Choose a Contribution slot and use the Shared UI.
  5. Keep the API reference open while implementing.