Eximia Download

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

FieldTypeRequiredMeaning
$schemastringrecommendedSchema URL for editor support.
idstringyesGlobally unique identifier. Kebab-case, prefixed with slm-eximia-.
namestringyesShort human/JS-friendly name. Used as the plugin name in the bridge.
versionstringyesSemVer. Follows the plugin's own release cycle, not SLMEximia's.
descriptionstringnoOne-line summary, surfaced in slm-eximia plugin list.
platformsstring[]yesSubset of ["android", "ios"].
jsobjectyesJS surface. See below.
androidobjectconditionalRequired iff "android" in platforms.
iosobjectconditionalRequired iff "ios" in platforms.
hooksobject[]noBuild-time scripts. See Hooks.
serialboolnoIf true, plugin calls are serialised by the runtime. Default false.

js

FieldTypeRequiredMeaning
entrystringyesPath to the JS file the runtime injects.
globalAsstringnoIf set, the runtime exposes the plugin as window.<globalAs> for <script>-style use.
typesstringnoPath to a .d.ts file. Copied alongside entry for IDE support.

android

FieldTypeRequiredMeaning
packagestringyesJava/Kotlin package the plugin's classes live in.
mainClassstringyesFully qualified entry class — must implement SLMEximiaPlugin.
sourcesstring[]yesGlob patterns relative to the plugin root. Copied into the generated module.
minSdkintnoRaises the app's minSdk if higher than 24.
permissionsstring[]noInserted as <uses-permission> in the merged manifest.
manifeststringnoPath to a partial AndroidManifest.xml whose <application> children get merged.
dependenciesstring[]noGradle coordinates, added as implementation in the app's build.gradle.kts.
fileProviderobjectnoIf the plugin needs a FileProvider, declare it here so the runtime registers it once.

ios

FieldTypeRequiredMeaning
mainClassstringyesSwift class name (must be @objc and conform to SLMEximiaPlugin).
sourcesstring[]yesGlob patterns relative to the plugin root.
minDeploymentTargetstringnoRaises the app's deployment target if higher than 13.0.
infoPlistobjectnoKeys merged into the app's Info.plist. Usage strings, etc.
frameworksstring[]noSystem frameworks to link.
swiftPackageDependenciesobject[]noSwiftPM packages: { url, from }.
cocoaPodsDependenciesstring[]no(Discouraged) CocoaPods dependencies as Pod 'Name', '~> X.Y'.

hooks

FieldTypeRequiredMeaning
stagestringyesOne of before-add, after-add, before-build, after-build.
runstringyesPath to an executable script inside the plugin. Runs in a sandboxed CWD.
platformsstring[]noLimit 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