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": "string",
"label": "Primary color",
"default": "#6366f1"
}
}
}
Fields
$schema
| Type | Required |
|---|---|
string | No |
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
| Type | Required |
|---|---|
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
| Type | Required | Max length |
|---|---|---|
string | Yes | 255 characters |
The display name shown in the extension store and dashboard. Use title case. Keep it concise and descriptive.
"name": "Sports Scoreboard"
description
| Type | Required | Max length |
|---|---|---|
string | Yes | 1000 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
| Type | Required |
|---|---|
enum | Yes |
The extension's primary category. Used for store filtering and browsing.
| Value | Description |
|---|---|
"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
| Type | Required |
|---|---|
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 truth — lumio deploy reads it automatically. You can also override it with the -v flag.
targets
| Type | Required |
|---|---|
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"]
| Value | Surface |
|---|---|
"editor" | Dashboard sidebar panel |
"layer" | Browser Source overlay |
"interactive" | Standalone audience page |
server
| Type | Required | Default |
|---|---|---|
boolean | No | false |
Enable server functions. When true, the server/ directory is bundled and deployed as server-side code.
"server": true
permissions
| Type | Required |
|---|---|
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
| Type | Required |
|---|---|
object | No |
Outbound network allowlist for ctx.fetch() in server actions. See Egress.
"egress": {
"allowHosts": ["api.example.com", "*.example.com"],
"allowPorts": [8443]
}
fonts
| Type | Required |
|---|---|
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"]
visibility
| Type | Required | Default |
|---|---|---|
enum | No | "private" |
Controls who can see and install the extension.
| Value | Access |
|---|---|
"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
| Type | Required | Default |
|---|---|---|
object | No | { "type": "free" } |
Pricing configuration. See Pricing for details.
"pricing": { "type": "free" }
config_schema
| Type | Required |
|---|---|
object | No |
User-facing settings schema. Fields defined here appear in an auto-generated settings panel and are accessible via useLumioConfig().
"config_schema": {
"primaryColor": {
"type": "string",
"label": "Primary color",
"default": "#6366f1"
},
"showTimestamp": {
"type": "boolean",
"label": "Show timestamp",
"default": true
},
"maxItems": {
"type": "number",
"label": "Maximum items to show",
"default": 5
}
}
Supported field types: "string", "number", "boolean".
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.
| Check | Example |
|---|---|
| Type match | A number field rejects string values |
| Required fields | Fields with required: true must be present and non-null |
| Select options | select fields only accept values from the declared options array |
| Color format | color fields must be valid #RRGGBB hex strings |
| Unknown keys | Keys 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.
platforms
| Type | Required |
|---|---|
string[] | Conditional |
Declares which chat platforms the extension supports. Required when category is "bot_module", ignored for other categories.
"platforms": ["twitch", "youtube", "kick"]
| Value | Platform |
|---|---|
"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
| Type | Required |
|---|---|
object | No |
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-field | Type | Description |
|---|---|---|
commands | array | Chat commands with prefix matching. Max 20. |
keywords | string[] | Substring matches. Min 3 chars each. Max 50. |
patterns | string[] | Regex patterns. Max 200 chars each. Max 10. |
events | string[] | Platform event types. |
timers | array | Recurring handlers. Min 60s interval. |
See Triggers for the full reference with validation rules and available event types.