Reference

Extensions

Extensions run code inside a space with rich access to the workspace: the API client, the active editor, and live collaboration state. Use it to add custom views, navigation entries, editor suggestions, and much more.

Browse documentation

An extension is a small package: a manifest.json plus one or more built JavaScript entry points. Once installed into a space, its entry modules load with the space and run against the extension context described below.

Anatomy of an extension

Every extension is described by a manifest.json at its root:

manifest.json
{
  "id": "kanban",
  "name": "Kanban",
  "version": "1.0.3",
  "description": "Group database records into kanban columns by a status property",
  "entries": {
    "frontend": "dist/main.js",
    "view": "dist/view.js"
  },
  "routes": [
    {
      "path": "kanban",
      "title": "Kanban",
      "menuItem": { "title": "Kanban", "icon": "<svg>…</svg>" },
      "placements": ["page"]
    }
  ]
}
FieldDescription
idUnique extension identifier. Lowercase alphanumeric with hyphens.
nameHuman-readable display name.
versionSemantic version. Bumped automatically on each package.
descriptionShort summary shown in the extensions settings panel.
entriesBuilt entry points: frontend (loaded globally) and view (route renderer).
routesPages the extension contributes, with optional navigation menu items.

The frontend entry loads globally while the space is open; the view entry renders a specific route. Routes may be placed on their own page ("page", the default) and/or on the space home ("home-top") via the placements array.

Scaffold a new extension

Use the CLI to generate a starter package. Run it from the directory that holds your extensions (it writes to an extensions/<id> folder). The id must be lowercase alphanumeric with hyphens:

Terminal
vektor extension create my-extension

This creates a minimal package:

  • manifest.json: id, name, a single route, and the built entry paths.
  • src/view.ts: an activate/deactivate module that registers a view.
  • package.json: a build script that bundles src to dist with Bun.

Authoring a view

An entry module exports activate and deactivate functions. Both receive an ExtensionContext. Register a renderer for your route with ctx.views.register and tear it down in deactivate:

src/view.ts
import type { ExtensionContext } from "../../../extension-api/types.ts";

export function activate(ctx: ExtensionContext): void {
  ctx.views.register("my-extension", (container) => {
    container.innerHTML = `<div class="p-6"><h1>My Extension</h1></div>`;

    // return an optional cleanup function
    return () => { container.innerHTML = ""; };
  });
}

export function deactivate(ctx: ExtensionContext): void {
  ctx.views.unregister("my-extension");
}

The extension context

The context is the extension's window into the workspace. Key members:

  • spaceId, documentId, route: where the extension is running.
  • api: the API client for reading and writing workspace data.
  • views: register/unregister a route renderer.
  • suggestions: register a provider for a trigger character (e.g. / or #) in the editor.
  • actions: register/unregister named actions.
  • getActiveEditor(): the active Tiptap editor, or null.
  • collaboration: the active Yjs session (ydoc, clientId) for synced state, or null.

Build & package

Packaging bumps the manifest's patch version, runs the build script, and zips the manifest.json together with the dist output:

Terminal
vektor extension package my-extension

The result is my-extension.zip in the extension directory, ready to install. Omit the id to package the extension in the current directory (it uses the folder name and its manifest.json).

Install

There are two ways to install a packaged extension into a space.

From the settings panel

Open your space settings, go to Extensions, and upload the generated .zip. Extensions can be updated the same way, and updating them later is supported from the same panel.

From the CLI

Upload the package directly to a space. This posts the zip to the space's extensions endpoint and requires a valid VEKTOR_ACCESS_TOKEN:

Terminal
vektor extension upload my-extension

For the full command reference, see the Extensions section of the CLI guide.