Codelet logoCodelet

Using extensions

Adding views, commands, panels, language support and filesystems to a workbench through the extensions option

An extension is an object you pass to extensions on the workbench. Some are values you import directly; some are functions you call to set options. Pass a few together:

import { Workbench } from "codelet/workbench";
import { search } from "codelet/extensions/search";
import { logs } from "codelet/extensions/logs";
import { media } from "codelet/extensions/media";

const workbench = new Workbench({
  parent: document.getElementById("app")!,
  extensions: [search, logs(), media],
});

search and media are extension objects. logs() is a function that returns one — that's how an extension takes options.

#Everything is opt-in

A workbench passed no extensions has no Search icon, no panel, no language support — none of it is built into the workbench itself. Each built-in lives at its own package entry (codelet/extensions/search, codelet/extensions/logs, and so on), so a page that never imports one never bundles it. What you add is the only cost past the workbench itself.

#Where extensions show up

  • Activity bar — an icon down the side that opens a sidebar view.
  • Panel — a tab along the foot of the editor, beside Problems. Logs and Terminal both add one.
  • Secondary side bar — a pane beside the editor rather than instead of the tree. Chat uses this.
  • Editor tab bar — a button at the right of the strip, over the file showing. The markdown preview button is one.
  • Context menus — the explorer's, a tab's, a view's own rows, and the document itself.
  • Command palette — every command an extension registered a handler for, under Mod-K or Mod-Shift-P.

How a manifest declares each of these, and what a command or a view can do once it's there:

Read more in API > Commands.
Read more in API > Views.

#Manifest and activation

Every extension has two halves. Its manifest — what it contributes to the activity bar, the panel, the palette, the tab bar — is plain data, read without running any of the extension's code. Its activate function is where the real work happens: workers start, sockets open, packages get fetched from a CDN.

That split is what lets the server render the shell around an extension without running it: the icon and the title come from the manifest, and activate only runs once the workbench mounts in a browser.

Warning

extensions is markup. Pass the exact same array, in the same order, to both renderWorkbench() on the server and Workbench on the client — or hydration has nothing to match and the shell rebuilds instead of taking over.

import { renderWorkbench } from "codelet/workbench/server";
import { EXTENSIONS } from "./extensions.ts";

const html = renderWorkbench({ extensions: EXTENSIONS });

#Starting and stopping an extension

codelet/extensions/extensions draws a card for every extension the workbench was given, what each one contributes, and a button that stops it and starts it again — without a reload.

import { extensions } from "codelet/extensions/extensions";
import { search } from "codelet/extensions/search";
import { logs } from "codelet/extensions/logs";

new Workbench({ parent, extensions: [extensions, search, logs()] });

#Every built-in

Read more in Extensions.

#Writing your own

Read more in API.