What plugins can add

React components

Custom UI panels and embedded components.

Commands

Explicit UI actions and slash-command style behaviors.

YAML views

Plugin-owned view documents persisted under the plugin views path.

Assistant tools

Function-style tools that the built-in assistant can call at runtime.

Executors

Runtime handlers for plugin tools and plugin-owned actions.

Lifecycle hooks

Startup and teardown logic via onLoad and onUnload.

Plugin models

In-tree plugins

Live under frontend/src/plugins, are imported during app startup, and are built with the main frontend. This is the model used by built-in plugin-style extensions such as coding agents.

Runtime-installed npm plugins

Installed with tamux install plugin <npm-package-or-local-path>. They ship as self-contained browser scripts that register themselves through window.TamuxApi.registerPlugin(...).

Runtime interface

export interface Plugin {
  id: string;
  name: string;
  version: string;
  components?: Record<string, React.ComponentType<any>>;
  commands?: Record<string, CommandAction>;
  views?: Record<string, unknown>;
  assistantTools?: PluginAssistantToolDefinition[];
  assistantToolExecutors?: Record<string, PluginAssistantToolExecutor>;
  onLoad?: () => void;
  onUnload?: () => void;
}

Names are namespaced automatically. Components become ${plugin.id}:${name}. The same namespacing logic applies to commands.

Packaging contract

Runtime-installed plugins should expose a tamuxPlugin field in package.json (the older amuxPlugin alias is still accepted for compatibility).

{
  "name": "tamux-plugin-example",
  "version": "0.6.3",
  "tamuxPlugin": {
    "entry": "dist/tamux-plugin.js",
    "format": "script"
  }
}
  • entry is required.
  • Only format: "script" is currently supported.
  • The entry bundle must be self-contained and directly executable in the renderer.
  • Published packages must already contain built entry assets because installers run with npm install --ignore-scripts.

Views, commands, and tools

Extension pointWhen to use itTypical output
ComponentsYou need custom UICustom panels and renderable nodes
CommandsYou need explicit user-triggered actionsButtons, command palette actions, slash-style actions
ViewsYou own a whole surfacePlugin YAML views under views/plugins
Assistant toolsThe built-in assistant should call your plugin directlyFunction-tool style schemas + runtime execution

A plugin should not add a core view just because it can. Use a plugin when the feature is truly plugin-owned or vertical-specific.

Gmail plugin pattern

The repository includes a Gmail/Calendar plugin package whose manifest shows the shape of a runtime-installed integration:

  • plugin metadata (name, version, compatibility)
  • auth block (OAuth2, scopes, PKCE)
  • settings fields
  • API base URL and endpoint templates
  • commands mapped to actions
  • optional bundled skills

That is a good reference for service plugins. More ambitious vertical plugins can use the same extension model but add plugin-owned views and assistant tools on top.

Author workflow

  1. Decide whether the plugin is in-tree or runtime-installed.
  2. Define the plugin id, surface area, and namespaced commands/components.
  3. Create views and components only where the plugin truly owns a workflow.
  4. Add assistant tools only when the built-in assistant should invoke the plugin directly.
  5. Package as a self-contained script if you want runtime installation.
  6. Install with tamux install plugin and validate in the actual UI runtime.

Plugin vs. core

Use a plugin when the feature is a domain-specific extension, owns its own UI/workflow, or adds commands/tools that should stay decoupled from tamux core.
Use core when the feature belongs to tamux itself: daemon state, built-in mission control, native task/goals flows, or platform-wide primitives.