Skip to content

What is an extension?

A Silo extension is a small object with an id and an activate function. The host calls activate once at startup and hands it an ExtensionContext — usually called ctx. Everything your extension adds to the app, it adds through ctx.

ts
import type { Extension } from "@silo-code/sdk";

export const extension: Extension = {
  id: "acme.hello",
  activate(ctx) {
    // register viewers, commands, panels… against ctx here
  },
};

That's the whole contract (Extension). There's an optional deactivate() for cleanup, reserved for when dynamic load/unload lands.

The one rule

An extension touches the running app only through ctx and the @silo-code/sdk types. It never imports app internals.

This isn't a style preference — it's enforced (a lint rule fails the build if an extension reaches into the app's state, services, or UI directly). The payoff is that extensions stay decoupled from the app's internals, so the app can evolve without breaking them. The status-bar toggle below — a complete extension — imports nothing but SDK types.

ts
import type { Extension } from "@silo-code/sdk";
import { useServiceState } from "@silo-code/sdk";

export const extension: Extension = {
  id: "acme.panel-toggle",
  activate(ctx) {
    const { layout } = ctx;

    function PanelToggles() {
      const state = useServiceState(layout);       // read state via a typed service
      return (
        <button
          className={state.left.collapsed ? "" : "active"}
          onClick={() => ctx.executeCommand("view.toggleLeftPanel")}  // act via a command
        >

        </button>
      );
    }

    ctx.registerStatusItem({ id: "panel-toggles", alignment: "right", component: PanelToggles });
  },
};

It reads state through a typed service (ctx.layout) and acts by invoking a command (ctx.executeCommand) — never by importing the app's store.

How ctx is organized

Everything ctx offers falls into three groups:

GroupWhat it's for
Registrationregister* methods that add things to the app — viewers, side panels, status items, commands, keybindings, menu items, file types, dock panels, settings pages. Each returns a Disposable.
Statetyped services that read & drive app state — ctx.workspaces (workspaces and editor tabs) and ctx.layout (side-panel collapse) — so you never reach into the store.
Otherctx.executeCommand(id) to invoke any registered command, plus ctx.extensionId and ctx.subscriptions.

The API Reference walks through every member of each group, with signatures, examples, and links to the type definitions.

Next