The official SDK for building plugins for Binder — a developer-focused terminal IDE built with Go + React.
Plugins are installable at runtime through the in-app Plugin Store. They can add new tab types, contribute slash commands to the terminal, and interact with the host application through a sandboxed API.
# Clone the plugin template
git clone https://github.com/BinderTools/plugin-template my-plugin
cd my-plugin
npm install
# Build a production bundle
npm run build
# → produces dist/index.js (the plugin bundle)The Plugin Store fetches dist/index.js from your public GitHub repository's default branch.
- A plugin is a single JavaScript file (ESM bundle) that exports a
Pluginobject as its default export. - When a user installs your plugin from the Plugin Store, Binder downloads
dist/index.jsfrom your GitHub repository and caches it locally. - On next launch, the app dynamically loads the cached bundle and registers the plugin.
- If your plugin declares a
tabType, Binder routes/your-commandterminal commands andapp:open-tabevents with that type to yourTabComponent.
importReactfrom'react'importtype{Plugin,PluginTabProps}from'@binder/plugin-sdk'functionMyTab({ context }: PluginTabProps){const{ executeCommand, cwd }=contextreturn(<divstyle={{padding: 16,color: '#ccc'}}><p>Working directory: {cwd??'unknown'}</p><buttononClick={()=>executeCommand?.('ls -la')}>
List files
</button></div>)}constplugin: Plugin={id: 'my-plugin',name: 'My Plugin',description: 'A minimal example plugin.',author: 'your-github-handle',version: '1.0.0',tabType: 'my-plugin',tabTitle: 'my plugin',TabComponent: MyTab,}exportdefaultpluginYour plugin repository must include:
my-plugin/
dist/
index.js ← compiled ESM bundle (required)
src/
index.tsx ← plugin source
package.json ← metadata (name, version, description, author, pluginId)
README.md
| Field | Description |
|---|---|
name | Display name shown in the Plugin Store |
version | Semver version string |
description | Short description shown in the Plugin Store |
author | Author name or GitHub handle |
pluginId | Unique kebab-case ID (falls back to the repo name if omitted) |
Use any bundler that can output a single ESM file. Example with Vite:
// vite.config.tsimport{defineConfig}from'vite'importreactfrom'@vitejs/plugin-react'exportdefaultdefineConfig({plugins: [react()],build: {lib: {entry: 'src/index.tsx',formats: ['es'],fileName: ()=>'index.js',},rollupOptions: {// Bundle React — the host app's React is not exposed to plugins// external: ['react'],},outDir: 'dist',},})- Getting Started — step-by-step walkthrough
- API Reference — full type reference for all SDK interfaces
- Building a Plugin — build tooling, packaging, and publishing guide
MIT