Plugin Structure

Each plugin lives in its own directory inside the VMSC plugins folder. At minimum, a plugin needs a manifest and an entry point:

my-plugin/
├── manifest.json
└── index.js

Manifest

The manifest.json file describes your plugin and tells VMSC how to load it.

{
  "name": "my-plugin",
  "version": "1.0.0",
  "description": "My custom plugin",
  "entryPoint": "index.js"
}
FieldTypeDescription
namestringUnique plugin identifier (kebab-case recommended)
versionstringSemver version string
descriptionstringShort description shown in the Plugins UI
entryPointstringRelative path to the main JS file

Lifecycle

Your entry point must export two functions that VMSC calls to manage the plugin's lifecycle:

FunctionDescription
activate(context)Called when the plugin is enabled. Receives the plugin API context object. Use this to register event listeners and initialize state.
deactivate()Called when the plugin is disabled or VMSC shuts down. Use this to clean up listeners, timers, or open connections.

API Methods

The context object passed to activate() exposes the following APIs:

Events

MethodDescription
context.events.emit(event, data)Emit a stream event into the VMSC event bus. Other plugins and the rule engine will receive it.
context.events.on(event, handler)Subscribe to events from the event bus. The handler receives the event data object.

Configuration

MethodDescription
context.config.get(key)Read a value from the plugin's scoped configuration store.
context.config.set(key, value)Write a value to the plugin's scoped configuration store. Values are persisted across restarts.

Logging

MethodDescription
context.logger.info(message)Log an informational message.
context.logger.warn(message)Log a warning.
context.logger.error(message)Log an error. Errors also appear in the VMSC developer console.

Example Plugin

A minimal plugin that logs gift events from TikTok:

module.exports = {
  activate(context) {
    context.events.on('stream-event', (event) => {
      if (event.type === 'gift') {
        context.logger.info(`Gift received: ${event.data.giftName}`)
      }
    })
  },
  deactivate() {
    // Cleanup timers, connections, etc.
  }
}

Security Notes

Plugins Run with Full Privileges

Plugins execute in the main Electron process and have full access to the Node.js API. Only install plugins from sources you trust.

  • Plugins run in the main Electron process with no sandbox.
  • Full Node.js API access is available, including file system, network, and child processes.
  • Configuration keys are automatically scoped by plugin name to prevent cross-plugin access.