Plugin anatomy
A plugin combines a manifest, a frontend entry, and optionally a backend. The scaffold gives each part a place in a regular Node.js project.
What a plugin contains
The manifest.json identifies the plugin, selects widget or page, points to its entry, and declares permissions and any backend commands. The frontend entry exports createInstance(container, ctx). The host calls it with a DOM container and PluginContext; it returns a PluginInstance with unmount() and optional onResize() for widgets. See the frontend lifecycle guide.
A backend is optional. Shell and Go backends expose declared routes through the typed ctx.backend client; device management calls use ctx.rciManager through the host. Read the shell backend guide and RCI API guide for those boundaries.
What the host provides
PluginContext is passed to createInstance and exposes host services:
rciManagerqueues device operations;backendis present when the manifest declares a backend. See the RCI API guide and shell backend guide.storageandsharedStoragestore plugin data;deviceInfoprovides a device snapshot.theme,locale, andpaletteprovide current values and observable updates throughtheme$,locale$, andpalette$;i18nprovides localized messages. See the frontend lifecycle guide.telemetryfetches projected data;eventsis optional and appears when the manifest declares event permissions.overlaypresents modals and drawers, andcreateTicker()creates a host-managed ticker.pageRouteprovides navigation within page plugins;setTileTitlesets a widget's host tile title.
The SDK reference documents the complete PluginContext contract.
A plugin's path
Edit the source and manifest, run mndw pack to build frontend assets and stage runtime files in dist/, then run mndw zip to create the upload archive. Upload the ZIP through the dashboard's plugin management flow. A plugin with a backend requires approval before it can run; a plugin without one installs directly. The validation and packaging guide covers the archive, and install mndw covers the dashboard setup. On the router, mndwd serves plugin files and runs or proxies the declared backend.
Scaffold tree
This is the hello-widget scaffold with a shell backend:
hello-widget/
backend/
main.sh
i18n/
en.json
ru.json
manifest.json
package.json
src/
App.svelte
TableNameCell.svelte
index.ts
l10n.test.ts
table.test.ts
vitest.config.tsbackend/main.shhandles the scaffold's shell route.i18n/en.jsonandi18n/ru.jsonhold the English and Russian catalogs.manifest.jsondeclares the plugin identity, entry, and backend route.package.jsonis the plugin npm package manifest; it lists@mndw/sdk,@mndw/ui, the framework wrapper such as@mndw/ui-svelte, and the build and test tools.src/App.svelteimplements the widget view.src/TableNameCell.svelterenders a table cell used by the scaffold.src/index.tsexports the frontend plugin entry.src/l10n.test.tsandsrc/table.test.tscover the generated view and table cell.vitest.config.tsconfigures the scaffold's test runner.
Example plugins
Built-in plugins in plugins/builtin/ include device-info-widget, cpu-temp-widget, tx-rx-chart-widget, terminal-page, clock-widget, dns-lookup-widget, mws-page, clients-widget, and system-log-page. Uploadable examples in plugins/examples/ include backend-echo, demo-page, device-traffic-widget, and ping-widget.