Skip to content

DocsApps

Extensions

Updated Oct 20, 2026

An extension is a bundle of additions to the shell and the built-in apps, installed as one unit: a context menu action, an "open with" for a file type, a preview, a panel with its own little interface, a settings section, a card in the side rail, or a before-hook - any combination of them, declared once and activated together. Where a script is one behaviour running in the background, an extension is the shape you reach for when the thing you want shows up inside an app you already use.

What an extension can add

Every addition an extension makes goes through the same handful of places any contribution can (see Extending the shell and built-in apps for the full list): a command, a keybinding, a context menu action, a file handler, a preview, a settings section, a rail card, or a before/after-hook. What sets an extension apart from a script registering the same things one at a time is packaging - a person installs or removes the whole set together, sees every slot it touches before approving it, and can turn the whole thing off with one switch.

An extension's own interface - a panel, a settings section's content, a card - runs the same way a small self-contained app does: sandboxed, with no access to the page around it, talking back to the OS only through the same bridge a bundled app uses. Its logic - what a command does when run, what a hook decides, what a preview renders - runs in the same kind of sandboxed worker a script does, with only the access the person granted it.

The manifest, field by field

An extension is one folder: a manifest plus its own source and any panel markup. The manifest names an id, a display name, a version, an optional description, an optional entry file for logic that isn't just a panel, which permissions and agent tools it's asking for (the same lists a script declares), and a contributes section naming everything it adds.

The slots

SlotWhat it needs from the manifest
CommandAn id, a title, and an optional keyboard shortcut
Context menu actionWhich app it appears in, a label, and (optionally) the file extensions it shows up for
File handlerWhich file extensions or types it opens, and which panel opens when it does
PreviewWhich files it can preview, and which of its handlers renders one
PanelAn id, a title, its markup, and whether it opens as its own window or lives in the side rail
Settings sectionA label, search keywords, and the markup that renders inside Settings
Rail cardWhich part of the rail it belongs in, and its markup
HookWhich of the six before-hook moments it watches, and which handler decides
EventA pattern to match on the event bus, and which handler runs

Limits

An extension that contributes a command or an event handler keeps its worker warm for five minutes after its last call, the same idle window a script with those triggers gets, then shuts down until something needs it again; one that only contributes panels, previews or hooks has its worker torn down right after each call instead. A panel's markup is sandboxed exactly the way a bundled app's is - no reach into the page around it, no network access outside the same approval flow anything else uses, and nothing it renders can be a live app-native surface, only plain markup and script. Its approved build covers everything the person approved: the logic and every panel's markup together, so editing so much as one panel afterward stops it from activating until it is approved again.

Three extensions, worked through

A CSV preview. Contributes a preview handler for a spreadsheet-shaped file type and a context menu action labelled "Open as table"; opening one runs a panel that reads the file and renders it as a scrollable grid instead of raw text.

A "send to calendar" context action. Contributes a context menu action inside Notes: selecting a note and choosing it reads the note's content, asks the person to confirm a date, and creates a calendar event from it through the calendar app's own tool rather than reaching into its data directly.

A rail card. Contributes a small card that watches a pattern on the event bus and keeps a running count of it for the day - visits to a particular kind of file, or how many times a particular automation has fired - showing up in the side rail without a window of its own.

Where its code runs

An extension's logic runs in the exact same kind of sandbox a script does - no window, no direct line to the network, checked on every single call against the permissions you granted. See the Scripts guide for the full list of what that sandbox gives it (files, events, notifications, storage, network, tools, agents) and what it refuses (writing into the folder that holds installed apps, scripts, or other extensions - not even its own - no matter what's been granted).

A panel - the window or rail-card UI an extension shows you - runs in its own sandboxed frame too, with no access to the rest of the page and no way to read or write anything except through the same channel every installed app's UI uses. A panel can call back into its own extension's logic, and only its own - there is no way for it to reach any other extension's code.

Approving an extension

Before an extension can do anything, you approve exactly what code it is (its logic, and every panel it shows you) and exactly what it may touch, and you're shown exactly what it adds - which commands, context actions, file handlers, panels, and hooks, alongside the permissions. If the code or any panel changes afterward, it stops running until you approve the new version. Disabling an extension removes everything it added, immediately - the command disappears from the strip, the context action disappears from the menu, and so on - with nothing left behind.

Installing from the community, and sharing your own

Like scripts and apps, an extension can come from the community catalog - installed with a verified download and the exact permissions and slots it declares, both shown before you approve it. If you've built one worth sharing, it can be proposed back to the same catalog the same way.

What's next