# Building Your Own Extensions

Build extensions that add new capabilities to Nimbalyst -- custom editors, AI tools, panels, themes, and more. Extensions are self-contained packages with a manifest that declares their contributions.

Nimbalyst is open source, and the built-in extensions live alongside the app source in [github.com/nimbalyst](https://github.com/nimbalyst). The fastest way to learn the extension API is to read those built-in extensions.

## What Can Extensions Do?

* **Custom Editors** -- New ways to view and edit file types (spreadsheets, diagrams, 3D models)
* **AI Tools** -- Tools that Claude can use to interact with your extension
* **AI Completions** -- Call chat models (Claude, OpenAI, LM Studio) directly from your extension
* **Panels** -- Sidebar panels, fullscreen views, or floating windows
* **Themes** -- Custom color themes
* **Slash Commands** -- Commands users can invoke from the chat
* **File Icons** -- Custom icons for file types in the sidebar
* **New File Types** -- Add entries to the "New File" menu

## Quick Start

The recommended workflow is to create and iterate on extensions from inside Nimbalyst:

1. Enable **Extension Dev Tools** in Settings > Advanced
2. Use `File > New Extension Project` or ask Claude to run `/new-extension`
3. Describe the extension you want Claude to build from the starter scaffold
4. Ask Claude to build and install the extension with `extension_build` and `extension_install`
5. Use `extension_reload` for rebuild + reinstall during iteration

See [Getting Started](/extensions/building-extensions/getting-started.md) for a step-by-step walkthrough.

## Project Structure

A typical extension project:

```
my-extension/
  manifest.json       # Extension metadata and contributions
  package.json        # npm dependencies
  tsconfig.json       # TypeScript configuration
  vite.config.ts      # Build configuration
  src/
    index.ts          # Extension entry point (activate/deactivate)
    components/       # React components
    styles.css        # Scoped styles
```

## Development Workflow

1. **Create** -- Use `/new-extension` inside Nimbalyst or copy a starter project
2. **Develop** -- Edit files in your extension project
3. **Build** -- Claude uses `extension_build` to compile
4. **Install** -- Claude uses `extension_install` to load it
5. **Test** -- Open a file with your extension's file type
6. **Iterate** -- Claude uses `extension_reload` for hot updates

## Core Concepts

### The Extension Manifest

Every extension needs a `manifest.json` that describes what it provides. At minimum:

```json
{
  "id": "com.example.my-editor",
  "name": "My Editor",
  "version": "1.0.0",
  "main": "dist/index.js"
}
```

See [Manifest Reference](/extensions/building-extensions/manifest-reference.md) for the complete schema.

### The EditorHost Contract

Custom editors receive a `host` prop that handles all communication with Nimbalyst -- loading and saving files, tracking dirty state, theme changes, and AI diff mode. The `useEditorLifecycle` hook wraps the host into a single, clean API.

See [Custom Editors](/extensions/building-extensions/custom-editors.md) for the full guide.

### AI Tool Integration

AI tools let Claude interact with your editor programmatically. Define tools with a name, description, input schema, and handler function. Claude reads the description to decide when to call your tool.

See [AI Tools](/extensions/building-extensions/ai-tools.md) for examples and best practices.

### Permissions

Extensions declare the capabilities they need:

| Permission   | What It Grants                                             |
| ------------ | ---------------------------------------------------------- |
| `filesystem` | Read and write files in the workspace                      |
| `ai`         | Register AI tools and call chat/completion models directly |
| `network`    | Make HTTP requests to external services                    |

## Documentation

| Document                                                                    | Description                               |
| --------------------------------------------------------------------------- | ----------------------------------------- |
| [Getting Started](/extensions/building-extensions/getting-started.md)       | Create your first extension in 10 minutes |
| [Custom Editors](/extensions/building-extensions/custom-editors.md)         | Build editors for new file types          |
| [AI Tools](/extensions/building-extensions/ai-tools.md)                     | Add tools that Claude can use             |
| [Manifest Reference](/extensions/building-extensions/manifest-reference.md) | Complete manifest.json schema             |
| [API Reference](/extensions/building-extensions/api-reference.md)           | TypeScript types and interfaces           |

## Prerequisites

* Nimbalyst with Extension Dev Tools enabled (Settings > Advanced)
* Node.js 18+
* Basic knowledge of React and TypeScript

## Built-in Extension Examples

Study the built-in extensions for patterns and best practices:

| Extension       | File Types       | Notable Patterns                           |
| --------------- | ---------------- | ------------------------------------------ |
| Excalidraw      | `.excalidraw`    | Imperative API via refs, 19 AI tools       |
| CSV Spreadsheet | `.csv`, `.tsv`   | RevoGrid with custom save, formula support |
| DataModelLM     | `.datamodel`     | Zustand store, screenshot export           |
| MockupLM        | `.mockup.html`   | iframe preview, AI generation              |
| SQLite Browser  | `.db`, `.sqlite` | Panel-based with Jotai, 9 AI tools         |

These are all in `packages/extensions/` in the [Nimbalyst repository on GitHub](https://github.com/nimbalyst).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.nimbalyst.com/extensions/building-extensions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
