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.
import React from 'react'
import type { Plugin, PluginTabProps } from '@binder/plugin-sdk'
function MyTab({ context }: PluginTabProps) {
const { executeCommand, cwd } = context
return (
<div style={{ padding: 16, color: '#ccc' }}>
<p>Working directory: {cwd ?? 'unknown'}</p>
<button onClick={() => executeCommand?.('ls -la')}>
List files
</button>
</div>
)
}
const plugin: 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,
}
export default pluginYour 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.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
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