For developers

Build on it

Client addons

An addon is a folder you drop in. A theme is CSS and goes into the page. A plugin is JavaScript and does not: it gets a worker of its own, and one object in it.

addonWorker.ts
declare const gryt: {
  version: string;
  theme: { appearance: "light" | "dark"; accentColor: string };
  on(event: "themeChange" | "cleanup", handler: () => void): () => void;

  // needs "status"
  setActivity(activity: string): Promise<unknown>;

  // needs "messaging"
  messaging: {
    send(topic: string, data: unknown, host?: string): Promise<unknown>;
    on(topic: string, handler: (message: unknown) => void): () => void;
    servers(): Promise<string[]>;
  };

  // needs "display"
  ui: {
    panel(panel: { title: string; rows: { label: string; value?: string }[] }): Promise<unknown>;
    clear(): Promise<unknown>;
  };

  // needs "processes"
  processes: {
    running(): Promise<string[]>;
    on(handler: (running: string[]) => void): () => void;
  };

  log: { info(m: string): void; warn(m: string): void; error(m: string): void };
};

Each of those needs a capability the manifest declared and the person turned on. Both, or the call rejects and says which one is missing. A capability name this build has never heard of is dropped rather than refused, so a plugin written against a newer Gryt still loads on an older one.

The other half of that is what a plugin doesn’t get, and it matters more than the list above:

not defined
window        // a worker has none, so nothing on the page
document
localStorage
indexedDB     // deleted off the prototype chain
caches
Worker        // no nesting out of it

A plugin can’t read your messages and can’t reach your identity key. It can put a panel beside the member list by describing one — a title and rows of text that Gryt draws — and it can’t put an element on the page, because it isn’t on the page.

What it keeps is its internet connection, so whatever you grant it, it can send anywhere. Installing one is still trusting whoever wrote it with what you gave it.