Extension Types
Understanding the different plugin architectures in Kunkun
Kunkun supports multiple plugin architectures for different use cases. Each type provides different capabilities, isolation levels, and development patterns.
Quick Comparison
| Type | Runtime | UI | Node.js Access | Use Case |
|---|---|---|---|---|
| Custom-View | BrowserWindow | Full control | No | Complex SPAs, dashboards |
| Worker-View | Web Worker | React via Uniview | No | Raycast-style extensions |
| Node-View | Node.js process | React via Uniview | Yes | Extensions needing filesystem |
| Worker-Headless | Web Worker | None | No | Background commands (browser) |
| Node-Headless | Node.js process | None | Yes | Background commands (system) |
| Service | Node.js process | None | Yes | Exposed APIs for other plugins/AI |
Architecture Diagram
┌─────────────────────────────────────────────────────────────────┐
│ Plugin Modes │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ UI Plugins │ │ Headless │ │ Services │ │
│ │ │ │ Commands │ │ │ │
│ ├─────────────┤ ├─────────────┤ ├─────────────────────────┤ │
│ │ custom-view │ │ worker- │ │ node-headless with │ │
│ │ worker-view │ │ headless │ │ services[] declaration │ │
│ │ node-view │ │ node- │ │ │ │
│ │ │ │ headless │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
│ │ │ │ │
└─────────┼────────────────┼──────────────────────┼───────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ Runtimes │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ BrowserWindow│ │ Web Worker │ │ Node.js Process │ │
│ │ (iframe) │ │ (sandboxed) │ │ (sandboxed) │ │
│ │ │ │ │ │ │ │
│ │ Full DOM │ │ No DOM │ │ Node.js APIs │ │
│ │ Any Framework│ │ React/Uniview│ │ Deno or Node │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘UI Plugins
Custom-View
Runtime: BrowserWindow with custom protocol (kunkun-ext://)
Custom-view plugins are static SPAs loaded into isolated BrowserWindows. You have full control over the UI using any frontend framework.
{
"name": "my-command",
"mode": "custom-view",
"main": "/",
"dist": "build",
"devMain": "http://localhost:5173"
}When to use:
- You need full UI control
- Converting existing web apps
- Complex interactive components
- Framework-specific features (Svelte, Vue, etc.)
Features:
- Origin isolation per plugin
- Any frontend framework works
- Full DOM access
- Standard web development workflow
Learn more: Custom UI Extension
Worker-View
Runtime: Browser Web Worker with Uniview renderer
Worker-view plugins run React components in Web Workers. The host renders the UI, ensuring consistent styling.
{
"name": "my-command",
"mode": "worker-view",
"main": "dist/App.js"
}When to use:
- Raycast-style extensions
- Simple UI components
- Data processing extensions
- Maximum isolation needed
Features:
- Sandboxed execution
- Consistent UI via host rendering
- React component model
- Fast startup
Node-View
Runtime: Node.js process (Deno, Node.js, or Electron utilityProcess)
Node-view plugins run React components in Node.js processes, providing filesystem and system access.
{
"name": "my-command",
"mode": "node-view",
"main": "dist/node/App.js",
"runtime": "auto"
}Runtime Selection:
| Priority | Runtime | Condition |
|---|---|---|
| 1 | Deno | Available (better sandboxing) |
| 2 | Node.js v20+ | Available with permission model |
| 3 | utilityProcess | Fallback (no sandbox) |
When to use:
- Need filesystem access
- Shell command execution
- Native module access
- System integration
Headless Commands
Worker-Headless
Runtime: Browser Web Worker
Background commands without UI. Useful for event-triggered actions and background processing.
{
"name": "my-headless",
"mode": "worker-headless",
"main": "dist/Headless.js"
}Lifecycle:
init() → onTrigger(ctx) → destroy()When to use:
- Clipboard monitoring
- Event-triggered actions
- Quick background tasks
Node-Headless
Runtime: Node.js process
Background commands with full system access. Same lifecycle as worker-headless but runs in Node.js.
{
"name": "my-headless",
"mode": "node-headless",
"main": "dist/node/Headless.js"
}When to use:
- File system operations
- Long-running background tasks
- System-level operations
Service Plugins
Runtime: Node.js process with services[] declaration
Service plugins expose callable methods that other plugins and the AI agent can invoke.
{
"services": [
{
"name": "math",
"description": "Basic math operations",
"main": "dist/node/MathService.js",
"serviceMode": "node-headless",
"methods": [
{
"name": "add",
"description": "Add two numbers",
"inputSchema": {
"type": "object",
"properties": {
"a": { "type": "number" },
"b": { "type": "number" }
},
"required": ["a", "b"]
},
"outputSchema": {
"type": "object",
"properties": {
"result": { "type": "number" }
}
}
}
]
}
]
}When to use:
- Shared utilities across plugins
- AI agent tools
- Cross-plugin communication
- Background services
Key Features:
- JSON Schema for input/output validation
- Automatic AI agent tool bridging
- Cross-plugin calling with permission intersection
- Lifecycle hooks (
onInit,onDestroy)
Choosing the Right Type
| Need | Recommended Type |
|---|---|
| Full UI control | Custom-View with your preferred framework |
| Raycast-like development | Worker-View for consistent UI without Node.js access |
| Filesystem access | Node-View for React UI with system capabilities |
| Background processing | Worker-Headless (browser) or Node-Headless (system) |
| Exposed APIs | Service plugins for cross-plugin/AI tool access |
Security Model
| Runtime | Isolation | Permission Model |
|---|---|---|
| BrowserWindow | Origin isolation | Manifest + runtime prompts |
| Web Worker | Worker sandbox | Manifest only |
| Node.js (Deno) | Process + Deno sandbox | Manifest + Deno flags |
| Node.js (v20+) | Process + Node sandbox | Manifest + Node flags |
| utilityProcess | Process only | Manifest only |
Deno is preferred for Node.js plugins because its permission model (--allow-net=domain.com) restricts network access at the process level, unlike Node.js which is all-or-nothing.