Plugin Manifest
Complete reference for plugin manifest configuration
Plugin Manifest
The manifest file (manifest.json) is the heart of every Orbis plugin. It defines metadata, pages, routes, permissions, and configuration.
Plugin Types
Orbis supports two types of plugins:
-
Manifest-only plugins: Pure UI with no server logic (pages, state, actions only)
- Great for dashboards, reports, and simple UIs
- No compilation needed - just JSON
- Limited to client-side operations
-
WASM plugins: Full-featured with server-side logic using the Orbis SDK
- API routes with database access, HTTP requests, etc.
- Rust/WASM compilation required
- Minimal boilerplate with
orbis_plugin!()andwrap_handler! - See WASM Plugins for SDK documentation
This document covers the manifest structure common to both types.
Basic Structure
{
"name": "my-plugin",
"version": "1.0.0",
"description": "My awesome plugin",
"author": "Your Name",
"homepage": "https://example.com",
"license": "MIT",
"min_orbis_version": "1.0.0",
"dependencies": [],
"permissions": [],
"pages": [],
"routes": [],
"wasm_entry": "plugin.wasm",
"config": {}
} Metadata Fields
name (Required)
Unique plugin identifier.
"name": "my-plugin" Rules:
- Alphanumeric characters, hyphens, and underscores only
- Must be unique across all installed plugins
- Case-sensitive
version (Required)
Semantic version string.
"version": "1.0.0" Format: MAJOR.MINOR.PATCH (e.g., 1.2.3)
Optional pre-release: 1.0.0-beta.1
description
Human-readable description.
"description": "A plugin that does awesome things" author
Plugin author or organization.
"author": "Your Name <[email protected]>" homepage
URL to plugin documentation or homepage.
"homepage": "https://github.com/user/my-plugin" license
SPDX license identifier.
"license": "MIT" Common values: MIT, Apache-2.0, GPL-3.0, BSD-3-Clause
Compatibility
min_orbis_version
Minimum required Orbis version.
"min_orbis_version": "1.0.0" Orbis will refuse to load plugins requiring a newer version.
Dependencies
Other plugins this plugin requires.
"dependencies": [
{
"name": "auth-plugin",
"version": ">=1.0.0"
},
{
"name": "data-plugin",
"version": "^2.0.0"
}
] Version Specifiers
| Specifier | Meaning |
|---|---|
1.0.0 | Exact version |
>=1.0.0 | 1.0.0 or higher |
>1.0.0 | Greater than 1.0.0 |
<=1.0.0 | 1.0.0 or lower |
<1.0.0 | Less than 1.0.0 |
^1.0.0 | Compatible with 1.x.x |
~1.0.0 | Approximately 1.0.x |
* | Any version |
Permissions
Capabilities requested by the plugin.
"permissions": [
{
"type": "network",
"allowed_hosts": ["api.example.com"]
},
{
"type": "storage",
"scope": "plugin-data"
}
] Permission Types
network
HTTP/HTTPS request permissions.
{
"type": "network",
"allowed_hosts": [
"api.example.com",
"*.myservice.io",
"https://secure.example.com"
]
} Wildcards (*) match any subdomain.
storage
Database/storage access.
{
"type": "storage",
"scope": "plugin-data",
"read": true,
"write": true
} Scopes:
plugin-data- Plugin’s isolated storageshared-read- Read access to shared datafull- Full database access (requires admin approval)
filesystem
Local file access.
{
"type": "filesystem",
"paths": [
{ "path": "$HOME/Documents/MyApp", "access": "read-write" },
{ "path": "/tmp/my-plugin", "access": "read-write" }
]
} Variables:
$HOME- User’s home directory$TEMP- Temporary directory$PLUGIN- Plugin’s directory
ipc
Inter-plugin communication.
{
"type": "ipc",
"allowed_plugins": ["auth-plugin", "data-plugin"]
} notification
System notifications.
{
"type": "notification"
} Pages
UI pages exposed by the plugin.
"pages": [
{
"route": "/my-plugin/dashboard",
"title": "Dashboard",
"icon": "LayoutDashboard",
"state": {},
"sections": [],
"hooks": {
"on_mount": [],
"on_unmount": []
}
}
] Page Fields
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique page ID |
title | string | Yes | Display title |
route | string | Yes | URL path |
icon | string | ❌ | lucide-react icon name |
state | object | ❌ | State definition |
layout | object | Yes | Root component schema |
on_mount | array | ❌ | Actions on page load |
on_unmount | array | ❌ | Actions on page leave |
See Page Definitions for full details.
Routes
API routes for backend functionality (WASM plugins only).
"routes": [
{
"path": "/api/items",
"method": "GET",
"handler": "get_items",
"middleware": ["auth"]
},
{
"path": "/api/items",
"method": "POST",
"handler": "create_item"
},
{
"path": "/api/items/:id",
"method": "GET",
"handler": "get_item"
},
{
"path": "/api/items/:id",
"method": "PUT",
"handler": "update_item"
},
{
"path": "/api/items/:id",
"method": "DELETE",
"handler": "delete_item"
}
] Route Fields
| Field | Type | Required | Description |
|---|---|---|---|
path | string | Yes | Route path (supports :param) |
method | string | Yes | HTTP method (GET, POST, PUT, DELETE, PATCH) |
handler | string | Yes | WASM function name (SDK: use wrap_handler!()) |
middleware | array | ❌ | Applied middleware |
Handler Implementation with SDK
When using the Orbis SDK, handlers are simple functions wrapped with wrap_handler!():
use orbis_plugin_api::sdk::prelude::*;
pub fn get_items_impl(ctx: Context) -> Result<Response> {
let items: Vec<Item> = state::get("items").unwrap_or_default();
Ok(Response::json(&items))
}
pub fn create_item_impl(ctx: Context) -> Result<Response> {
let new_item: NewItem = ctx.body_as()?;
// ... business logic
Ok(Response::json(&created_item))
}
wrap_handler!(get_items, get_items_impl);
wrap_handler!(create_item, create_item_impl); The SDK automatically:
- Parses request data
- Handles memory management
- Serializes responses
- Manages errors
See WASM Plugins for complete SDK documentation.
Path Parameters
{
"path": "/api/users/:userId/posts/:postId",
"method": "GET",
"handler": "get_user_post"
} Parameters are passed to the handler function.
Middleware
Built-in middleware:
| Name | Description |
|---|---|
auth | Requires authenticated user |
admin | Requires admin role |
rate-limit | Applies rate limiting |
WASM Entry
Path to the compiled WASM binary (required for WASM plugins).
"wasm_entry": "my_plugin.wasm" Deployment Options:
-
External file (recommended with SDK):
~/.orbis/plugins/my-plugin/ ├── my_plugin.wasm └── manifest.json -
Manifest embedded in WASM:
- Use
add_custom_section.pyto embed manifest as custom section - Manifest can be omitted in this case
- Use
With SDK: Just build with cargo build --target wasm32-unknown-unknown --release and place alongside manifest.json.
Configuration
Custom plugin configuration.
"config": {
"api_base_url": "https://api.example.com",
"max_items": 100,
"features": {
"advanced_mode": true
}
} Configuration is accessible in WASM handlers and can be used in expressions:
{
"type": "Text",
"content": "Max items: {{config.max_items}}"
} Complete Example
{
"name": "task-manager",
"version": "2.1.0",
"description": "A comprehensive task management plugin",
"author": "Orbis Team",
"homepage": "https://github.com/orbis/task-manager",
"license": "MIT",
"min_orbis_version": "1.0.0",
"dependencies": [
{
"name": "auth-plugin",
"version": ">=1.0.0"
}
],
"permissions": [
{
"type": "storage",
"scope": "plugin-data"
},
{
"type": "notification"
}
],
"pages": [
{
"title": "Tasks",
"route": "/tasks",
"icon": "CheckSquare",
"show_in_menu": true,
"state": {
"tasks": { "type": "array", "default": [] },
"filter": { "type": "string", "default": "all" }
},
"sections": [
{
"type": "Container",
"className": "p-6",
"children": [
{
"type": "PageHeader",
"title": "My Tasks",
"subtitle": "Manage your daily tasks"
}
]
}
],
"hooks": {
"on_mount": [
{
"type": "call_api",
"api": "task-manager.get_tasks",
"on_success": [
{ "type": "update_state", "path": "tasks", "from": "$response.data" }
]
}
]
}
}
],
"routes": [
{
"path": "/api/tasks",
"method": "GET",
"handler": "get_tasks"
},
{
"path": "/api/tasks",
"method": "POST",
"handler": "create_task"
},
{
"path": "/api/tasks/:id",
"method": "PUT",
"handler": "update_task"
},
{
"path": "/api/tasks/:id",
"method": "DELETE",
"handler": "delete_task"
}
],
"wasm_entry": "task_manager.wasm",
"config": {
"max_tasks": 1000,
"enable_notifications": true
}
} Validation
Orbis validates manifests at load time:
- Required fields are checked
- Version format is verified
- Routes are validated
- Permissions are checked against capability system
Invalid manifests produce detailed error messages.
Best Practices
Naming
- Use lowercase with hyphens:
my-awesome-plugin - Be descriptive but concise
- Avoid generic names like
pluginorapp
Versioning
- Follow semantic versioning strictly
- Bump major version for breaking changes
- Document changes in CHANGELOG.md
Permissions
- Request minimum necessary permissions
- Document why each permission is needed
- Users can see permission requests before installing
Dependencies
- Keep dependencies minimal
- Use version ranges to allow updates
- Test with dependency updates
Next Steps
- Page Definitions - Detailed page configuration
- WASM Plugins - Backend plugin development
- Building Plugins - Build and packaging
On This Page
- Plugin Types
- Basic Structure
- Metadata Fields
- name (Required)
- version (Required)
- description
- author
- homepage
- license
- Compatibility
- min_orbis_version
- Dependencies
- Version Specifiers
- Permissions
- Permission Types
- Pages
- Page Fields
- Routes
- Route Fields
- Handler Implementation with SDK
- Path Parameters
- Middleware
- WASM Entry
- Configuration
- Complete Example
- Validation
- Best Practices
- Naming
- Versioning
- Permissions
- Dependencies
- Next Steps