Skip to main content

lumio.config.json Reference

The manifest file at the root of every extension project. It defines the extension's identity, capabilities, and distribution settings.

Full reference

{
"$schema": "https://lumio.vision/schemas/lumio.config.schema.json",
"extensionId": "88b2478a-39c7-468e-bebd-14e52fd97ac0",
"name": "Sports Scoreboard",
"description": "Display live sports scores from ESPN on your stream overlay.",
"category": "widget",
"version": "1.2.0",
"targets": ["editor", "layer"],
"server": true,
"permissions": ["chat:send"],
"egress": {
"allowHosts": ["site.api.espn.com", "cdn.espn.com"],
"allowPorts": []
},
"fonts": ["Inter", "Roboto Mono"],
"visibility": "public",
"pricing": {
"type": "free"
},
"config_schema": {
"primaryColor": {
"type": "color",
"label": "Primary color",
"default": "#6366f1"
},
"fontSize": {
"type": "slider",
"label": "Font size",
"default": 16,
"min": 8,
"max": 72,
"unit": "px"
}
}
}

Fields

$schema

TypeRequired
stringNo

URL to the JSON Schema file for editor validation and autocompletion in VS Code. Always use:

"$schema": "https://lumio.vision/schemas/lumio.config.schema.json"

This URL points to a live, dynamically generated JSON Schema served by the Lumio web app. It is NOT a static file — the schema is generated at runtime and reflects the current config format (including triggers, platforms, and config_schema fields).

The endpoint is CORS-open (Access-Control-Allow-Origin: *) so VS Code and other editors can fetch it for autocompletion and validation without authentication.


extensionId

TypeRequired
string (UUID v4)Yes

The unique identifier assigned to your extension when it was created via lumio init or the dashboard. It must be a valid UUID that exists in the Lumio database.

"extensionId": "88b2478a-39c7-468e-bebd-14e52fd97ac0"

You cannot change this value after creation. The Extension-ID is how Lumio links your deployed bundle to your extension record.


name

TypeRequiredMax length
stringYes255 characters

The display name shown in the extension store and dashboard. Use title case. Keep it concise and descriptive.

"name": "Sports Scoreboard"

description

TypeRequiredMax length
stringYes1000 characters

A short description of what the extension does. Used in the store listing and dashboard. Plain text only — no Markdown.

"description": "Display live sports scores from ESPN on your stream overlay."

category

TypeRequired
enumYes

The extension's primary category. Used for store filtering and browsing.

ValueDescription
"widget"Standalone visual element (scoreboard, timer, now playing)
"extension"General-purpose extension that doesn't fit another category
"overlay"Full-screen transparent layer overlay
"bot_module"Chat bot command or moderation module
"integration"External service connector (Discord, StreamElements)
"theme"Visual style pack for overlays

version

TypeRequired
string (semver)Yes

Semantic version of the extension. Must follow MAJOR.MINOR.PATCH format.

"version": "1.2.0"

The version in lumio.config.json is the source of truthlumio deploy reads it automatically. You can also override it with the -v flag.


targets

TypeRequired
string[]Conditional

Which surfaces the extension renders on. At least one target is required for widget, overlay, extension, integration, and theme categories. Bot module extensions (category: "bot_module") have no visual surfaces and should omit this field or set it to an empty array.

"targets": ["editor", "layer"]
ValueSurface
"editor"Dashboard sidebar panel
"layer"Browser Source overlay
"interactive"Standalone audience page
"designer"Fullpage designer overlay with split pane

server

TypeRequiredDefault
booleanNofalse

Enable server functions. When true, the server/ directory is bundled and deployed as server-side code.

"server": true

permissions

TypeRequired
string[]No

Lumio service actions the extension needs. Shown to users at install time — users must grant consent. See Permissions for the full list.

"permissions": ["chat:send", "obs:set_scene"]

egress

TypeRequired
objectNo

Outbound network allowlist for ctx.fetch() in server actions. See Egress.

"egress": {
"allowHosts": ["api.example.com", "*.example.com"],
"allowPorts": [8443]
}

fonts

TypeRequired
string[]No

Google Fonts to preload for the extension. Font names must match the Google Fonts name exactly.

"fonts": ["Inter", "Roboto Mono", "Press Start 2P"]

sounds

TypeRequiredDefault
arrayNo[]

Declare audio files to bundle with the extension. Bundled sounds are added to the user's sound library on install and removed on uninstall. Users cannot delete or rename them.

"sounds": [
{ "file": "alert.mp3", "name": "Alert" },
{ "file": "chime.wav", "name": "Chime", "default_volume": 0.8 }
]
FieldTypeRequiredDescription
filestringYesRelative path in dist/sounds/. 1-255 characters.
namestringYesDisplay name in the Sounds Panel. 1-255 characters.
default_volumenumberNoDefault playback volume (0.0-1.0).

Supported formats: MP3, WAV, OGG, WebM, M4A, AAC, FLAC. Default limit: 50 sounds per extension (admin-configurable). Place audio files in dist/sounds/ before running lumio deploy.


visibility

TypeRequiredDefault
enumNo"private"

Controls who can see and install the extension.

ValueAccess
"private"Only the developer can see and install
"unlisted"Anyone with the direct link can install
"public"Listed in the extension store
"paid"Listed in the store, requires purchase (developer verification required)

pricing

TypeRequiredDefault
objectNo{ "type": "free" }

Pricing configuration. See Pricing for details.

"pricing": { "type": "free" }

config_schema

TypeRequired
objectNo

User-facing settings schema. Fields defined here appear in an auto-generated settings panel and are accessible via useLumioConfig().

"config_schema": {
"primaryColor": {
"type": "color",
"label": "Primary color",
"default": "#6366f1"
},
"showTimestamp": {
"type": "boolean",
"label": "Show timestamp",
"default": true
},
"maxItems": {
"type": "slider",
"label": "Maximum items to show",
"default": 5,
"min": 1,
"max": 50,
"step": 1
},
"font": {
"type": "font",
"label": "Display font",
"default": "Inter"
},
"displayOptions": {
"type": "group",
"label": "Display Options",
"collapsed": true,
"fields": {
"opacity": {
"type": "slider",
"label": "Opacity",
"default": 100,
"min": 0,
"max": 100,
"unit": "%"
}
}
}
}

Supported field types

TypeDescriptionKey properties
stringSingle-line text inputplaceholder
numberNumeric inputmin, max, step
booleanToggle switch
colorColor picker with hex input
selectDropdown with predefined optionsoptions
textareaMulti-line text inputplaceholder, rows
sliderRange slidermin, max, step, unit
fontFont family picker (Google Fonts)
iconIcon picker (Lucide, emoji, emotes, uploads)
imageImage upload or URL
soundSound picker — selects a sound from the account's sound library. Value is a UUID (sound ID). SchemaEditor renders a dropdown picker.
multiselectMultiple selection from optionsoptions, multiple
groupCollapsible group of nested fieldsfields, collapsed
dividerVisual separator (no value)
infoRead-only informational text (no value)content
channelMulti-platform channel picker
designerFullpage designer surface fieldpresets

Common field properties

Every field type supports:

PropertyTypeDescription
labelstringDisplay label (required for all types)
defaultvariesDefault value
requiredbooleanWhether the field must have a value
visible_whenobjectConditional visibility — show the field only when another field has a specific value

Server-side validation

Config values are validated against your config_schema when users save settings — both through the dashboard and via the API. Invalid values are rejected with descriptive error messages.

CheckExample
Type matchA number field rejects string values
Required fieldsFields with required: true must be present and non-null
Select optionsselect and multiselect fields only accept values from the declared options array
Color formatcolor fields must be valid #RRGGBB or #RRGGBBAA hex strings
Slider rangeslider values must be within min/max bounds
Unknown keysKeys not declared in config_schema are rejected

Extensions can trust that ctx.config values match the declared types at runtime — the API enforces this before writing to the database.

The sound field type

A sound field lets users pick a sound from their account's sound library. The stored value is a UUID string (the sound ID) or null if no sound is selected. The SchemaEditor renders this as a dropdown populated with all sounds in the account's library, including extension-bundled sounds.

{
"config_schema": {
"alertSound": {
"type": "sound",
"label": "Alert sound",
"default": null
}
}
}

At runtime, ctx.config.alertSound holds the sound ID (UUID string) or null. Pass this ID to the useLumioSound hook to play the configured sound.

Auto-generated settings UI

Fields defined in config_schema are automatically rendered in a settings panel by the SchemaEditor component — no custom editor.tsx needed. Extensions can use config_schema alone, a custom editor.tsx alone, or both (schema fields render first, custom editor below).


designer_schema

TypeRequired
arrayNo

An array of field definitions for the fullpage designer surface. The designer provides a split-pane view with a live preview alongside configuration fields. Fields use the same type system as config_schema.

"designer_schema": [
{
"key": "layout",
"type": "select",
"label": "Layout",
"default": "horizontal",
"options": [
{ "value": "horizontal", "label": "Horizontal" },
{ "value": "vertical", "label": "Vertical" }
]
}
]

Unlike config_schema (which is an object keyed by field name), designer_schema is an array where each entry includes a key property.


platforms

TypeRequired
string[]Conditional

Declares which chat platforms the extension supports. Required when category is "bot_module", ignored for other categories.

"platforms": ["twitch", "youtube", "kick"]
ValuePlatform
"twitch"Twitch IRC chat
"youtube"YouTube Live chat
"kick"Kick chat
"trovo"Trovo chat
"discord"Discord (bot modules only)

Bots only match triggers for extensions that support their platform. A Twitch-only extension does not receive YouTube messages.

Discord is restricted to bot module extensions — widget, overlay, and theme extensions cannot target Discord.


triggers

TypeRequired
objectNo

Defines when bot module handlers fire. Only allowed when category is "bot_module" — other categories with a triggers field are rejected at validation.

"triggers": {
"commands": [
{
"name": "points",
"description": "Show your points balance",
"cooldown_global": 5,
"cooldown_user": 10,
"min_role": "everyone"
}
],
"keywords": ["gg", "nice shot"],
"patterns": ["https?://clips\\.twitch\\.tv/\\S+"],
"events": ["twitch:subscribe", "twitch:raid"],
"timers": [
{
"name": "reminder",
"interval": 300,
"handler": "periodicReminder"
}
]
}
Sub-fieldTypeDescription
commandsarrayChat commands with prefix matching. Max 20.
keywordsstring[]Substring matches. Min 3 chars each. Max 50.
patternsstring[]Regex patterns. Max 200 chars each. Max 10.
eventsstring[]Platform event types.
timersarrayRecurring handlers. Min 60s interval.

See Triggers for the full reference with validation rules and available event types.