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
An extension reaches a space either from the store, or as a zip you push yourself.
From the extension store
Open your space settings, go to Extensions → Store, and pick one from the catalogue. Your server downloads the package from the registry, checks it against the SHA-256 the registry published, and re-validates the manifest before installing — so what runs is exactly what was published. The same install from the CLI:
vektor extension install kanban # latest published version
vektor extension install kanban 1.1.33 # a specific oneInstalled store extensions record where they came from, so a space can tell later which of its extensions were reviewed and which were side-loaded. A store is a plain HTTP registry that anyone can host, so a server can be pointed at a mirror, or at one of your own, with VEKTOR_MARKETPLACE_URL.
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.