Skip to content

Latest commit

 

History

History
133 lines (100 loc) · 3.37 KB

File metadata and controls

133 lines (100 loc) · 3.37 KB

Binder Plugin SDK

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.


Quick start

# 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.


How plugins work

  1. A plugin is a single JavaScript file (ESM bundle) that exports a Plugin object as its default export.
  2. When a user installs your plugin from the Plugin Store, Binder downloads dist/index.js from your GitHub repository and caches it locally.
  3. On next launch, the app dynamically loads the cached bundle and registers the plugin.
  4. If your plugin declares a tabType, Binder routes /your-command terminal commands and app:open-tab events with that type to your TabComponent.

Minimal plugin example

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 plugin

Repository structure

Your 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

package.json fields

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)

Build setup

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',
  },
})

Documentation


License

MIT