Skip to content

Latest commit

 

History

History
135 lines (103 loc) · 3.73 KB

File metadata and controls

135 lines (103 loc) · 3.73 KB

Getting Started

This guide walks you through creating, testing, and publishing your first Binder plugin.

Prerequisites

  • Node.js 18+
  • A public GitHub repository
  • Binder installed

1. Create your repository

Create a new public repository on GitHub. The repository name becomes your plugin's default ID, so use kebab-case (e.g. plugin-file-tree).

2. Set up the project

mkdir my-plugin && cd my-plugin
npm init -y
npm install --save-dev vite @vitejs/plugin-react typescript react react-dom
npm install --save-dev @types/react @types/react-dom

Add the Plugin SDK types. Since the SDK is included in Binder's build, you reference it as a type-only package:

npm install --save-dev @binder/plugin-sdk

The SDK package contains only TypeScript interfaces — no runtime code. React is bundled with your plugin (not a peer dependency) unless you choose to externalize it.

3. Write your plugin

Create src/index.tsx:

import React, { useState } from 'react'
import type { Plugin, PluginTabProps } from '@binder/plugin-sdk'

function MyTab({ context }: PluginTabProps) {
  const { executeCommand, cwd } = context
  const [output, setOutput] = useState<string>('')

  const run = (cmd: string) => {
    executeCommand?.(cmd)
    setOutput(`▶ ${cmd}`)
  }

  return (
    <div style={{ padding: '16px', fontFamily: 'monospace', color: '#ccc' }}>
      <h3 style={{ margin: '0 0 12px', color: '#ddd' }}>My Plugin</h3>
      <p style={{ color: '#666', fontSize: 12 }}>cwd: {cwd ?? 'unknown'}</p>
      <button onClick={() => run('ls -la')}
        style={{ background: 'rgba(79,195,247,0.1)', border: '1px solid rgba(79,195,247,0.25)',
                 color: '#4fc3f7', padding: '6px 14px', borderRadius: 5, cursor: 'pointer' }}>
        List files
      </button>
      {output && <pre style={{ marginTop: 12, color: '#888', fontSize: 11 }}>{output}</pre>}
    </div>
  )
}

const plugin: Plugin = {
  id: 'my-plugin',            // must be unique; use kebab-case
  name: 'My Plugin',
  description: 'A minimal example Binder plugin.',
  author: 'your-github-handle',
  version: '1.0.0',
  tabType: 'my-plugin',       // the tab type opened by /my-plugin in the terminal
  tabTitle: 'my plugin',      // text shown on the tab
  TabComponent: MyTab,
}

export default plugin

4. Configure the build

Create 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',
    },
    outDir: 'dist',
    // Do NOT set rollupOptions.external — bundle React with the plugin
  },
})

Create tsconfig.json:

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "Node",
    "jsx": "react-jsx",
    "strict": true,
    "noEmit": true
  },
  "include": ["src"]
}

5. Build and test

npm run build
# → dist/index.js

To test in Binder, open the Plugin Store (/plugins), go to the External tab, and paste your repository URL. If you haven't pushed yet, you can temporarily serve the bundle locally and use ngrok or a local IP — but for the best experience, push to GitHub and install directly.

6. Publish

  1. Push your code including the dist/ folder to GitHub
  2. Make sure your repository is public
  3. Open Binder → /plugins → External tab → paste your GitHub repo URL → Fetch & Install

Your plugin is now installed and its tab type is available.

Next steps

  • API Reference — all interfaces, props, and context methods
  • Building a Plugin — advanced topics: slash commands, requirements check, CSS isolation