Scaffold
$ npx create-pairlens-plugin my-pluginYou 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
MarketAdapterinterface - 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.workspacesentry: 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
- MarketAdapter API if you are adding a venue
- Publish to the registry when it is ready to ship
