For builders

Create a plugin

Scaffold a plugin with create-pairlens-plugin, implement a capability, build a zip, and load it into a running terminal.

Updated 22 AUG 20264 min readEdit on GitHub ↗

Scaffold

$ npx create-pairlens-plugin my-plugin

You get a ready-to-build folder: a manifest.json, a sample panel built with @pairlens/ui and @pairlens/plugin-sdk, and build and package scripts.

Declare a capability

The manifest is the contract. It carries your plugin’s id, version, the capabilities it provides, the network hosts it needs, and a contributes block for panels and workspaces.

What you implement depends on what you declared:

  • A market connector implements the MarketAdapter interface
  • An AI provider exposes getLanguageModel()
  • A theme provides theme:override
  • A panel exports a React component named in contributes.panels
  • A ready-made layout is a contributes.workspaces entry: an id, store copy, browse facets, and a column/cell/pane layout. No code, and no capability to declare, since a layout only arranges panels the user already has
  • An indicator provider ships chart:indicator

Declare the minimum. Every capability and every host is something a user has to agree to, and something a reviewer will question.

Build and package

bun run build     # bundles src/index.ts to dist/module.js as ESM
bun run package   # zips manifest.json + module.js (+ styles.css if present)

The output is a single .zip. That is the distributable unit.

Note

Mark React, @pairlens/plugin-sdk, @pairlens/ui, and @pairlens/fast-financial-charts as build externals. The host provides them at runtime, so bundling your own copies bloats the package and duplicates the WebGL chart engine.

Load it

In the terminal, go to Plugins → Installed and use Import plugin, or drag the zip onto the page. On desktop you can also drop the folder into the plugins directory.

Rebuild, re-import, and iterate. The dev-starter-plugin and dev-sync-plugin examples in the repo are working references.

Styling

Design-system components are styled by the host, so importing from @pairlens/ui gets you the user’s active theme for free, across all eighteen of them. For anything custom, ship a styles.css alongside your module and the packager includes it.

Use the theme’s CSS variables rather than hard-coded colours. A plugin that looks right in the default dark theme and unreadable in High Contrast is a plugin people uninstall.

Note

During development your plugin runs with the same sandbox and network allowlist it will have in production, so you catch permission gaps early rather than after publishing.

Next

Was this page helpful?Thanks, noted

Search docs

Search docs, guides, and commands