Developer Guide
Build API v5 extensions
This guide is for extension authors shipping browser-side JS modules. It covers the runtime contract, app-owned UI surfaces, local dev flow, and marketplace packaging without dumping every internal type on one page.
Who this guide is for
Use these docs if you are writing a JS extension that runs in the browser, reads the active chat or persona context, exposes tools to the model, or renders UI inside the app.
Good fit
You want to build an extension in devextensions/, test it in the app, and later publish it.
You need the public runtime contract, not a tour of internal app code.
Not this guide
It does not document every frontend implementation detail or the internal built-in extension codebase.
It does not document every internal frontend implementation detail or the private authoring notes used by repo maintainers.
Build flow
Most extensions follow the same path: define a manifest, add runtime behavior, test fromdevextensions/, then turn the same manifest and JS source into a marketplace draft.
- 1Create a manifest and JS module that target API v5.
- 2Add tools, hooks, and optional app UI only where the extension actually needs them.
- 3Load the extension through the Dev Extensions screen, then refresh it from disk while you iterate.
- 4Submit the same code as an unpublished marketplace draft when you want broader testing.
Start here
This is the smallest useful extension shape: a manifest, useExtension(), one tool, and one executeTool() handler.
export const manifest = {
apiVersion: 6,
version: '1.0.0',
key: 'hello-extension',
name: 'Hello Extension',
category: 'integration',
icon: 'Sparkles',
description: 'Adds one simple browser-side tool.',
};
export function useExtension() {
return {
isInstalled: true,
isAvailable: true,
isEnabled: true,
isActive: false,
statusIndicator: { color: 'yellow', label: 'Ready' },
globalSettings: {},
personaSettings: {},
resolvedSettings: {},
enable: async () => {},
disable: async () => {},
updateGlobalSettings: async () => {},
updatePersonaSettings: async () => {},
updateSettings: async () => {},
};
}
export function getTools() {
return [
{
type: 'function',
function: {
name: 'say_hello',
description: 'Return a short greeting.',
parameters: {
type: 'object',
properties: {
name: { type: 'string' },
},
required: ['name'],
},
},
},
];
}
export async function executeTool(name, args) {
if (name !== 'say_hello') {
throw new Error(`Unknown tool: ${name}`);
}
return { message: `Hello, ${args.name}.` };
}Guide map
Runtime
Runtime hub plus dedicated references for manifest fields, exports, prompt contributions, runtime APIs, and versioning.
UI surfaces
Settings schema, inheritance, top-bar dropdowns, footer drawer, panel sections, prompt state, and extension controls.
Workflow
Local dev folders, the Dev Extensions screen, marketplace draft submission, My Media, upload limits, and security.