Stream Kit Docs
Developers

Overlay authoring

Manifest schema, settings, events, and action presets for Stream Kit overlays.

Overlay authoring

Overlays are local web projects served by Stream Kit. Author overlays by editing the project files and overlay.manifest.json in the overlay folder.

Manifest

Each overlay includes overlay.manifest.json. For editor autocomplete, set $schema to the public JSON Schema:

{
	"$schema": "https://stream-kit.app/schemas/overlay-manifest.schema.json",
	"id": "my-alert-overlay",
	"name": "My Alerts",
	"framework": "svelte",
	"expectedEvents": ["alert", "clear"],
	"outgoingEvents": ["button:clicked", "alert:dismissed"],
	"settings": [],
	"testHandlers": [],
	"requiredPlugins": ["twitch"],
	"actions": []
}

Stream Kit also copies overlay-manifest.schema.json into new overlay projects for offline use (./overlay-manifest.schema.json).

FieldDescription
idStable overlay id (folder name)
nameDisplay name in the app
frameworkStarter template id (vanilla, svelte, react, …)
expectedEventsEvent names for Send to Overlay combobox (app → overlay)
outgoingEventsEvent names this overlay sends to Stream Kit (overlay → app); used for Message Received trigger setup
settingsConfigure page fields (text, switch, select, slider, color, file, sections)
testHandlersQuick test buttons on overlay detail page
requiredPluginsPlugin keys required for action presets
actionsOptional action presets to install

Settings

Settings fields render on the overlay Configure page. Values are broadcast to the browser source as event overlay:settings with a key-value map.

Supported field types: text, switch, checkbox, select, slider, color, select-file-or-folder, and grouped section blocks.

Use __overlay__ token in select items when a field should reference the current overlay id.

File settings

Use select-file-or-folder with mode: "file" (folders are not supported in overlay settings). With an active subscription, the Configure page shows Upload and Cloud (same cloud library as action handlers).

File values use two forms:

  • Stored config: cloud files remain host-independent /api/files/... refs so the overlay config works across PCs. Local files are stored as the absolute path returned by the desktop picker.
  • Configure page: cloud refs show as a full authenticated URL when cloud access is available. When Keep cloud files offline is enabled and the file is cached, the desktop UI may show the local cache path instead.
  • overlay:settings payload: cloud refs are always sent as full authenticated URLs. The desktop offline path is not sent to the browser source because it is not accessible from OBS's browser context. Local file paths are left unchanged, but they are only useful to desktop consumers.

Tokens on cloud URLs are refreshed while the app is running.

When a subscription becomes active (or when you open Configure), Stream Kit automatically uploads remaining local OS paths and overlay-relative defaults such as ./alert.webm from the overlay project into your cloud library and rewrites the setting to a /api/files/... ref.

{
	"type": "select-file-or-folder",
	"key": "logo",
	"name": "Logo",
	"mode": "file",
	"filters": [{ "name": "Images", "extensions": ["png", "jpg", "webp", "gif"] }]
}
'overlay:settings': (payload) => {
  logoEl.src = payload.logo || '';
}

Without a subscription, the field falls back to local Browse only. The desktop picker returns a full local path, but local absolute paths are not usable in OBS browser sources — prefer cloud file refs for overlay media.

Receiving events

The overlay runtime connects to ws://127.0.0.1:PORT/ws?overlayId=.... Incoming messages use this shape:

{ "event": "alert", "payload": { "username": "viewer" } }

The reserved event overlay:settings is only sent from Stream Kit to the overlay.

Sending events to Stream Kit

Use the starter's connectOverlay() helper, which returns a send() function:

const overlay = connectOverlay({
	'overlay:settings': (payload) => applySettings(payload),
	alert: (payload) => showAlert(payload)
});

document.getElementById('follow-btn')?.addEventListener('click', () => {
	overlay.send('button:clicked', { id: 'follow' });
});

Stream Kit receives these messages and can run actions via Overlay → Message Received (overlay:overlay:message-received).

Listen for inbound messages manually:

socket.addEventListener('message', (event) => {
	const { event: eventName, payload } = JSON.parse(event.data);
	if (eventName === 'alert') {
		showAlert(payload);
	}
});

Payload from actions

Send to Overlay payload supports two modes:

ModeUse when
JSONBuild a payload template with \{variables\}. Quoted standalone placeholders are cast to real JSON when the value is valid JSON (objects, arrays, numbers, booleans, or null). For example, "\{message\}" sends the object when {message} is a JSON object.
VariablePass one variable through unchanged — for example {message} when the trigger already provides a JSON object.

Leave payload empty to receive the full trigger context.

Handler ID: overlay:overlay:send-to-overlay.

Action presets

Presets bundle triggers and handlers users can install from the overlay page:

{
	"key": "follow-alert",
	"name": "Follow alert",
	"enabled": true,
	"triggers": [
		{
			"triggerTypeId": "twitch:twitch:channel:new-follower",
			"conditions": {}
		}
	],
	"handlers": [
		{
			"handlerTypeId": "overlay:overlay:send-to-overlay",
			"fields": [
				{ "key": "overlay", "value": "__overlay__" },
				{ "key": "event", "value": "alert" },
				{ "key": "payload", "value": "{\"username\":\"{username}\"}" }
			]
		}
	]
}

handlerTypeId and triggerTypeId must match API Reference IDs.

Editing code

From the overlay card, open the project folder in your editor or use the built-in open-folder action. Rebuild if your framework requires a build step (starters include dev scripts).

On this page