manifest.json v2.4 Schema
The manifest.json file is the central configuration for your BoardAPI component. It defines metadata, behavior, permissions, and integration points.
Schema Version
{
"$schema": "https://boardapi.io/schemas/manifest-v2.4.json"
}Basic Information
Required Fields
| Field | Type | Description |
|---|---|---|
name | string | Unique component identifier (lowercase, alphanumeric, hyphens) |
version | string | Semantic version (e.g., 1.0.0) |
title | string | Display name for users |
description | string | Brief description of component functionality |
Optional Metadata
| Field | Type | Description |
|---|---|---|
author | string | Author name and email (e.g., "John Doe <john@example.com>") |
license | string | License identifier (e.g., "MIT") |
repository | string | Git repository URL |
keywords | string[] | Search keywords for marketplace |
Example:
{
"name": "countdown-timer",
"version": "1.2.3",
"title": "Countdown Timer",
"description": "Interactive countdown timer with alerts",
"author": "John Doe <john@example.com>",
"license": "MIT",
"repository": "https://github.com/johndoe/countdown-timer",
"keywords": ["timer", "countdown", "productivity"]
}Entry Points
| Field | Type | Required | Description |
|---|---|---|---|
entry | string | Yes | Main JavaScript file (e.g., "component.js") |
styles | string | No | Main CSS file (e.g., "styles.css") |
Example:
{
"entry": "component.js",
"styles": "styles.css"
}Dimensions
Configure component size and resizing behavior.
| Field | Type | Default | Description |
|---|---|---|---|
width | number | 300 | Initial width in pixels |
height | number | 200 | Initial height in pixels |
minWidth | number | 200 | Minimum width |
minHeight | number | 150 | Minimum height |
maxWidth | number | - | Maximum width (optional) |
maxHeight | number | - | Maximum height (optional) |
resizable | boolean | true | Allow resizing |
aspectRatio | string | null | Lock aspect ratio: "16:9", "4:3", or null |
Example:
{
"dimensions": {
"width": 400,
"height": 300,
"minWidth": 300,
"minHeight": 200,
"maxWidth": 1000,
"maxHeight": 800,
"resizable": true,
"aspectRatio": "16:9"
}
}Props (Configuration)
Props are configurable values set by the host application. They generate a settings UI automatically.
Prop Schema
Each prop has:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Data type: string, number, boolean, array, object |
default | any | Yes | Default value |
description | string | No | Documentation |
ui | object | No | UI widget configuration |
UI Widget Types
| Widget | Type | Description |
|---|---|---|
text | string | Single-line text input |
textarea | string | Multi-line text input |
richtext | string | Rich text editor |
number | number | Number input |
slider | number | Range slider (with minimum/maximum) |
stepper | number | Increment/decrement buttons |
radio | string | Radio buttons (with enum) |
select | string | Dropdown select (with enum) |
buttons | string | Button group (with enum) |
color | string | Color picker |
color-array | string[] | Multiple color pickers |
Examples
String Props:
{
"props": {
"title": {
"type": "string",
"default": "My Timer",
"description": "Component title",
"ui": {
"label": "Title",
"placeholder": "Enter title...",
"widget": "text"
}
},
"description": {
"type": "string",
"default": "",
"ui": {
"label": "Description",
"widget": "textarea"
}
}
}
}Number Props:
{
"props": {
"duration": {
"type": "number",
"default": 300,
"minimum": 0,
"maximum": 3600,
"ui": {
"label": "Duration (seconds)",
"widget": "slider"
}
},
"fontSize": {
"type": "number",
"default": 16,
"minimum": 12,
"maximum": 48,
"ui": {
"label": "Font Size",
"widget": "stepper"
}
}
}
}Enum Props:
{
"props": {
"theme": {
"type": "string",
"enum": ["light", "dark", "auto"],
"default": "auto",
"ui": {
"label": "Theme",
"widget": "radio"
}
},
"layout": {
"type": "string",
"enum": ["horizontal", "vertical", "grid"],
"default": "horizontal",
"ui": {
"label": "Layout",
"widget": "select"
}
}
}
}Boolean Props:
{
"props": {
"showSeconds": {
"type": "boolean",
"default": true,
"ui": {
"label": "Show seconds"
}
}
}
}Array Props:
{
"props": {
"colors": {
"type": "array",
"items": { "type": "string", "format": "color" },
"default": ["#FF0000", "#00FF00", "#0000FF"],
"ui": {
"label": "Color palette",
"widget": "color-array"
}
}
}
}Storage (Shared State)
Define the schema for real-time synchronized data.
Schema Definition
Each storage key has:
| Field | Type | Description |
|---|---|---|
type | string | Data type: string, number, boolean, array, object |
default | any | Default value |
description | string | Documentation |
Visibility Modes (v2.2+)
| Mode | Description |
|---|---|
shared | Broadcast to all users (default) |
private | Stored on server, not broadcast |
anonymous | No userId attached |
Example:
{
"storage": {
"schema": {
"count": {
"type": "number",
"default": 0,
"description": "Click counter"
},
"lastClicker": {
"type": "string",
"description": "User ID of last clicker"
},
"history": {
"type": "array",
"items": {
"type": "object",
"properties": {
"userId": { "type": "string" },
"timestamp": { "type": "string", "format": "date-time" }
}
},
"maxItems": 100,
"description": "Click history"
},
"myVote": {
"type": "number",
"description": "User's private vote"
}
},
"visibility": {
"count": "shared",
"lastClicker": "shared",
"history": "shared",
"myVote": "private"
}
}
}Settings UI
Configure custom settings dialog.
| Field | Type | Default | Description |
|---|---|---|---|
mode | string | "auto" | "auto" (generated from props) or "custom" |
entry | string | - | Custom settings HTML file (if mode: "custom") |
width | number | 400 | Settings dialog width |
height | number | 500 | Settings dialog height |
Example:
{
"settings": {
"mode": "custom",
"entry": "settings.html",
"width": 500,
"height": 600
}
}Preview (Static Mode)
Configure static preview generation when component is off-screen.
| Field | Type | Default | Description |
|---|---|---|---|
mode | string | "auto" | "auto", "manual", or "disabled" |
format | string | "svg" | Preview format: "svg", "png", "webp" |
fallback | string | - | Fallback image path |
staleIndicator | boolean | true | Show indicator when preview is outdated |
staleTimeout | number | 5000 | Milliseconds before preview is marked stale |
Example:
{
"preview": {
"mode": "auto",
"format": "svg",
"fallback": "assets/placeholder.svg",
"staleIndicator": true,
"staleTimeout": 5000,
"generator": {
"selector": "#preview-root",
"width": 300,
"height": 200,
"scale": 1
}
}
}Rendering & Performance
Control lazy loading and rendering optimization.
| Field | Type | Default | Description |
|---|---|---|---|
lazyLoad | boolean | true | Load component only when in viewport |
viewport.margin | number | 200 | Pixels before viewport to start loading |
priority | string | "normal" | Render priority: "low", "normal", "high" |
keepAlive | boolean | false | Keep component loaded when off-screen |
keepAliveTimeout | number | 30000 | Milliseconds before unloading |
Example:
{
"rendering": {
"lazyLoad": true,
"viewport": {
"margin": 200
},
"priority": "high",
"keepAlive": true,
"keepAliveTimeout": 60000
}
}Backend & Secrets
Configure API proxying and secret management.
Backend Endpoints
{
"backend": {
"endpoints": [
{
"path": "/api/jira/*",
"target": "https://api.atlassian.com",
"auth": {
"type": "header",
"name": "Authorization",
"value": "Bearer {{JIRA_TOKEN}}"
},
"rateLimit": {
"requests": 100,
"window": "1m"
}
}
]
}
}Secrets
| Field | Type | Description |
|---|---|---|
description | string | Human-readable description |
required | boolean | Must be configured before use |
scope | string | "organization", "board", or "user" |
rotatable | boolean | Can be rotated/updated |
Example:
{
"secrets": {
"JIRA_TOKEN": {
"description": "Jira API Token",
"required": true,
"scope": "organization",
"rotatable": true
},
"OPENAI_KEY": {
"description": "OpenAI API Key",
"required": false,
"scope": "user",
"rotatable": true
}
}
}Permissions
Define role-based access control.
| Resource | Permissions | Description |
|---|---|---|
storage | ["read", "write"] | Access to shared state |
props | ["read", "write"] | Access to configuration |
backend | ["*"] or specific endpoints | API proxy access |
Example:
{
"permissions": {
"storage": {
"host": ["read", "write"],
"guest": ["read", "write"]
},
"props": {
"host": ["read", "write"],
"guest": ["read"]
},
"backend": {
"host": ["*"],
"guest": ["GET /api/jira/issues"]
}
}
}Global Events (v2.2+)
Cross-component communication via events.
| Field | Type | Description |
|---|---|---|
emit | string[] | Events this component can send |
listen | string[] | Events this component can receive |
Example:
{
"globalEvents": {
"emit": ["lesson:start", "lesson:end", "quiz:*"],
"listen": ["timer:*", "lesson:*"]
}
}Wildcard patterns (*) match multiple events.
Presence (Real-time Cursors)
Track and display user cursors inside the component.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable cursor tracking |
throttle | number | 50 | Throttle interval (ms) for cursor updates |
showCursors | boolean | true | Render cursors by default |
Example:
{
"presence": {
"enabled": true,
"throttle": 50,
"showCursors": true
}
}Undo/Redo
Integrate with global undo/redo stack (Ctrl+Z).
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable undo/redo integration |
maxHistory | number | 50 | Maximum checkpoints |
groupingTimeout | number | 1000 | Group changes within N ms |
Example:
{
"undoRedo": {
"enabled": true,
"maxHistory": 100,
"groupingTimeout": 500
}
}Debug & Logging
Configure remote logging for production debugging.
| Field | Type | Default | Description |
|---|---|---|---|
remoteLogs | boolean | false | Send logs to server |
logLevel | string | "error" | Minimum level: "debug", "info", "warn", "error" |
retention | string | "24h" | Log retention period |
Example:
{
"debug": {
"remoteLogs": true,
"logLevel": "warn",
"retention": "7d"
}
}Webhooks (v2.2+)
Receive external events from third-party services.
Example:
{
"webhooks": {
"jira": {
"events": ["issue:created", "issue:updated"],
"filter": {
"project": "MYPROJECT"
}
},
"github": {
"events": ["push", "pull_request:*"]
},
"custom": {
"endpoint": "/webhooks/my-service",
"secret": "{{MY_WEBHOOK_SECRET}}",
"events": ["*"]
}
}
}Export (v2.2+)
Define data export formats.
| Field | Type | Description |
|---|---|---|
formats | string[] | Built-in formats: "csv", "json", "xlsx", "pdf" |
customFormats | object | Custom export handlers |
Example:
{
"export": {
"formats": ["csv", "json", "xlsx"],
"customFormats": {
"report": {
"label": "Monthly Report",
"handler": "exports/monthly-report.js"
}
}
}
}Connectors (v2.2+)
Enable diagram-style connections between components.
Example:
{
"connectors": {
"enabled": true,
"ports": [
{
"id": "input-left",
"position": "left",
"offset": { "x": 0, "y": 50 },
"type": "input",
"accepts": ["data", "request"]
},
{
"id": "output-right",
"position": "right",
"offset": { "x": 100, "y": 50 },
"type": "output",
"outputs": ["response", "data"]
}
],
"validation": true
}
}Accessibility (v2.2+)
Configure accessibility features.
| Field | Type | Default | Description |
|---|---|---|---|
keyboardNavigation | boolean | false | Enable Tab/Arrow navigation |
screenReaderSupport | boolean | false | ARIA labels and live regions |
highContrastSupport | boolean | false | Respect prefers-contrast |
reduceMotionSupport | boolean | false | Respect prefers-reduced-motion |
role | string | - | ARIA role (e.g., "application") |
label | string | - | ARIA label |
Example:
{
"accessibility": {
"keyboardNavigation": true,
"screenReaderSupport": true,
"highContrastSupport": true,
"reduceMotionSupport": true,
"role": "application",
"label": "Interactive countdown timer"
}
}Internationalization (v2.2+)
Multi-language support.
| Field | Type | Description |
|---|---|---|
defaultLocale | string | Default locale code (e.g., "en") |
supportedLocales | string[] | Supported locale codes |
translations | object | Locale to translation file mapping |
dateFormat | string | "auto", "ISO", or "locale" |
numberFormat | string | "auto" or locale-specific |
Example:
{
"i18n": {
"defaultLocale": "en",
"supportedLocales": ["en", "ru", "de", "es", "zh"],
"translations": {
"en": "i18n/en.json",
"ru": "i18n/ru.json",
"de": "i18n/de.json"
},
"dateFormat": "locale",
"numberFormat": "auto"
}
}Offline Support (v2.2+)
Enable offline functionality and sync.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable offline support |
persistence | string | "indexeddb" | Storage: "indexeddb", "localstorage", "none" |
maxPendingOperations | number | 1000 | Queue size for offline operations |
retryStrategy | string | "exponential" | Retry: "exponential", "linear", "immediate" |
Example:
{
"offline": {
"enabled": true,
"persistence": "indexeddb",
"maxPendingOperations": 500,
"retryStrategy": "exponential"
}
}Performance Tuning (v2.2+)
Rate limiting and batching configuration.
Example:
{
"performance": {
"rateLimit": {
"debounce": 300,
"throttle": 50,
"maxBurst": 10
},
"batching": {
"enabled": true,
"maxBatchSize": 50,
"flushInterval": 100
}
}
}Runtime Assets (v2.3+)
User-uploaded files (images, audio, video).
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable file uploads |
maxFileSize | number | 10485760 | Max file size (bytes, default 10MB) |
maxTotalStorage | number | 104857600 | Total storage per board (default 100MB) |
allowedTypes | string[] | - | MIME types allowed |
Example:
{
"runtimeAssets": {
"enabled": true,
"maxFileSize": 5242880,
"maxTotalStorage": 52428800,
"allowedTypes": [
"image/jpeg",
"image/png",
"image/webp",
"audio/mpeg",
"video/mp4"
],
"imageOptimization": {
"maxWidth": 2000,
"maxHeight": 2000,
"quality": 85,
"format": "webp"
},
"thumbnails": {
"sizes": [100, 200, 400],
"format": "webp"
}
}
}Transient State (v2.3+)
High-frequency ephemeral updates (cursors, selections).
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable transient updates |
maxUpdatesPerSecond | number | 60 | Rate limit per key |
maxKeys | number | 10 | Concurrent transient keys |
maxPayloadSize | number | 1024 | Max bytes per update |
persistOnDisconnect | boolean | false | Save to DB on disconnect |
persistOnUnload | boolean | false | Save on page close |
Example:
{
"transient": {
"enabled": true,
"maxUpdatesPerSecond": 60,
"maxKeys": 5,
"maxPayloadSize": 512,
"persistOnDisconnect": false,
"persistOnUnload": false
}
}Marketplace
Configure marketplace listing.
| Field | Type | Description |
|---|---|---|
category | string | Category: "productivity", "education", "collaboration", etc. |
tags | string[] | Search tags |
pricing | string | "free", "paid", or "freemium" |
screenshots | string[] | Screenshot paths |
Example:
{
"marketplace": {
"category": "productivity",
"tags": ["timer", "countdown", "productivity"],
"pricing": "free",
"screenshots": [
"assets/screenshot-1.png",
"assets/screenshot-2.png"
]
}
}Migrations
Version migration scripts.
Example:
{
"migrations": {
"1.x-to-2.x": "migrations/1-to-2.js",
"2.0-to-2.1": "migrations/2.0-to-2.1.js"
}
}See CLI migrate command for details.
Complete Example
Minimal component manifest:
{
"$schema": "https://boardapi.io/schemas/manifest-v2.4.json",
"name": "my-timer",
"version": "1.0.0",
"title": "My Timer",
"description": "A simple countdown timer",
"author": "John Doe <john@example.com>",
"license": "MIT",
"entry": "component.js",
"styles": "styles.css",
"dimensions": {
"width": 300,
"height": 200,
"resizable": true
},
"props": {
"duration": {
"type": "number",
"default": 60,
"minimum": 1,
"maximum": 3600,
"ui": {
"label": "Duration (seconds)",
"widget": "slider"
}
}
},
"storage": {
"schema": {
"timeRemaining": {
"type": "number",
"default": 0
}
}
}
}Full example with all features:
{
"$schema": "https://boardapi.io/schemas/manifest-v2.4.json",
"name": "advanced-component",
"version": "2.4.0",
"title": "Advanced Component",
"description": "Full-featured example component",
"entry": "component.js",
"styles": "styles.css",
"dimensions": {
"width": 400,
"height": 300,
"minWidth": 300,
"minHeight": 200,
"resizable": true,
"aspectRatio": "16:9"
},
"props": {
"theme": {
"type": "string",
"enum": ["light", "dark", "auto"],
"default": "auto",
"ui": { "label": "Theme", "widget": "radio" }
}
},
"storage": {
"schema": {
"count": { "type": "number", "default": 0 },
"myVote": { "type": "number" }
},
"visibility": {
"count": "shared",
"myVote": "private"
}
},
"preview": {
"mode": "auto",
"format": "svg"
},
"rendering": {
"lazyLoad": true,
"priority": "normal"
},
"backend": {
"endpoints": [{
"path": "/api/data/*",
"target": "https://api.example.com",
"rateLimit": { "requests": 100, "window": "1m" }
}]
},
"permissions": {
"storage": { "host": ["read", "write"], "guest": ["read"] },
"props": { "host": ["read", "write"], "guest": ["read"] }
},
"globalEvents": {
"emit": ["component:*"],
"listen": ["lesson:*"]
},
"presence": { "enabled": true },
"undoRedo": { "enabled": true },
"accessibility": {
"keyboardNavigation": true,
"screenReaderSupport": true
},
"i18n": {
"defaultLocale": "en",
"supportedLocales": ["en", "ru"],
"translations": {
"en": "i18n/en.json",
"ru": "i18n/ru.json"
}
},
"marketplace": {
"category": "productivity",
"tags": ["example", "demo"],
"pricing": "free"
}
}