Eximia docs
Plugin manifest reference
Every SLMEximia plugin has a plugin.json at its root. It tells the CLI what
files are part of the plugin, where they go in the generated Android and
iOS projects, what native dependencies they pull in, and what permissions
the plugin needs.
The schema lives at schemas/plugin.schema.json
(JSON Schema draft 2020-12). Editors that support $schema URLs give
autocomplete out of the box.
Minimal example
{
"$schema": "https://eximia.testslm.site/schemas/plugin.schema.json",
"id": "slm-eximia-device-info",
"name": "DeviceInfo",
"version": "1.0.0",
"platforms": ["android", "ios"],
"js": {
"entry": "www/index.js",
"globalAs": "SLMDeviceInfo"
},
"android": {
"package": "com.slm.eximia.deviceinfo",
"mainClass": "com.slm.eximia.deviceinfo.SLMDeviceInfo",
"sources": ["src/android/**/*.kt"]
},
"ios": {
"mainClass": "SLMDeviceInfo",
"sources": ["src/ios/**/*.swift"]
}
}
That's enough for a plugin that only reads device info — no permissions, no native dependencies, no special build hooks.
Full example (Camera)
{
"$schema": "https://eximia.testslm.site/schemas/plugin.schema.json",
"id": "slm-eximia-camera",
"name": "Camera",
"version": "1.2.0",
"description": "Camera capture and gallery picker.",
"platforms": ["android", "ios"],
"js": {
"entry": "www/index.js",
"globalAs": "SLMCamera",
"types": "www/index.d.ts"
},
"android": {
"package": "com.slm.eximia.camera",
"mainClass": "com.slm.eximia.camera.SLMCamera",
"sources": ["src/android/**/*.kt", "src/android/**/*.java"],
"minSdk": 24,
"permissions": [
"android.permission.CAMERA",
"android.permission.READ_EXTERNAL_STORAGE"
],
"manifest": "src/android/AndroidManifest.xml",
"dependencies": [
"androidx.exifinterface:exifinterface:1.3.7",
"androidx.core:core-ktx:1.13.0"
],
"fileProvider": {
"authority": "${applicationId}.slmcamera.fileprovider",
"paths": "src/android/file_paths.xml"
}
},
"ios": {
"mainClass": "SLMCamera",
"sources": ["src/ios/**/*.swift"],
"minDeploymentTarget": "13.0",
"infoPlist": {
"NSCameraUsageDescription": "Used to capture photos.",
"NSPhotoLibraryUsageDescription": "Used to pick photos from the gallery."
},
"frameworks": ["AVFoundation", "Photos", "UIKit"]
},
"hooks": [
{
"stage": "after-add",
"run": "scripts/postinstall.sh",
"platforms": ["android"]
}
]
}
Field reference
Root
| Field | Type | Required | Meaning |
|---|---|---|---|
$schema | string | recommended | Schema URL for editor support. |
id | string | yes | Globally unique identifier. Kebab-case, prefixed with slm-eximia-. |
name | string | yes | Short human/JS-friendly name. Used as the plugin name in the bridge. |
version | string | yes | SemVer. Follows the plugin's own release cycle, not SLMEximia's. |
description | string | no | One-line summary, surfaced in slm-eximia plugin list. |
platforms | string[] | yes | Subset of ["android", "ios"]. |
js | object | yes | JS surface. See below. |
android | object | conditional | Required iff "android" in platforms. |
ios | object | conditional | Required iff "ios" in platforms. |
hooks | object[] | no | Build-time scripts. See Hooks. |
serial | bool | no | If true, plugin calls are serialised by the runtime. Default false. |
js
| Field | Type | Required | Meaning |
|---|---|---|---|
entry | string | yes | Path to the JS file the runtime injects. |
globalAs | string | no | If set, the runtime exposes the plugin as window.<globalAs> for <script>-style use. |
types | string | no | Path to a .d.ts file. Copied alongside entry for IDE support. |
android
| Field | Type | Required | Meaning |
|---|---|---|---|
package | string | yes | Java/Kotlin package the plugin's classes live in. |
mainClass | string | yes | Fully qualified entry class — must implement SLMEximiaPlugin. |
sources | string[] | yes | Glob patterns relative to the plugin root. Copied into the generated module. |
minSdk | int | no | Raises the app's minSdk if higher than 24. |
permissions | string[] | no | Inserted as <uses-permission> in the merged manifest. |
manifest | string | no | Path to a partial AndroidManifest.xml whose <application> children get merged. |
dependencies | string[] | no | Gradle coordinates, added as implementation in the app's build.gradle.kts. |
fileProvider | object | no | If the plugin needs a FileProvider, declare it here so the runtime registers it once. |
ios
| Field | Type | Required | Meaning |
|---|---|---|---|
mainClass | string | yes | Swift class name (must be @objc and conform to SLMEximiaPlugin). |
sources | string[] | yes | Glob patterns relative to the plugin root. |
minDeploymentTarget | string | no | Raises the app's deployment target if higher than 13.0. |
infoPlist | object | no | Keys merged into the app's Info.plist. Usage strings, etc. |
frameworks | string[] | no | System frameworks to link. |
swiftPackageDependencies | object[] | no | SwiftPM packages: { url, from }. |
cocoaPodsDependencies | string[] | no | (Discouraged) CocoaPods dependencies as Pod 'Name', '~> X.Y'. |
hooks
| Field | Type | Required | Meaning |
|---|---|---|---|
stage | string | yes | One of before-add, after-add, before-build, after-build. |
run | string | yes | Path to an executable script inside the plugin. Runs in a sandboxed CWD. |
platforms | string[] | no | Limit which platforms trigger the hook. Default both. |
Hooks SHOULD be avoided unless absolutely necessary; the manifest's declarative fields cover ~95% of what plugins typically need.
Validation
The CLI validates plugin.json against the schema on:
slm-eximia plugin add— refuses to add a plugin whose manifest is invalid.slm-eximia build— refuses to build if any installed plugin has an invalid manifest.
In CI you can run slm-eximia plugin validate path/to/plugin to check
without installing.
See also
schemas/plugin.schema.json— the schema itself, machine-readable.plugin-authoring.md— walkthrough for writing a new plugin from scratch.../cli/docs/commands/plugin.md— how the CLI consumes manifests.