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
Getting started
Operations
Changelog
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:
{
"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"]
}
]
}| Field | Description |
|---|---|
id | Unique extension identifier. Lowercase alphanumeric with hyphens. |
name | Human-readable display name. |
version | Semantic version. Bumped automatically on each package. |
description | Short summary shown in the extensions settings panel. |
entries | Built entry points: frontend (loaded globally) and view (route renderer). |
routes | Pages 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:
vektor extension create my-extensionThis creates a minimal package:
manifest.json: id, name, a single route, and the built entry paths.src/view.ts: anactivate/deactivatemodule that registers a view.package.json: abuildscript that bundlessrctodistwith 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:
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, ornull.collaboration: the active Yjs session (ydoc,clientId) for synced state, ornull.
Build & package
Packaging bumps the manifest's patch version, runs the build script, and zips the manifest.json together with the dist output:
vektor extension package my-extensionThe 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:
vektor extension upload my-extensionFor the full command reference, see the Extensions section of the CLI guide.