Plugin Development Setup

This guide explains how to develop and test plugins locally without going through a ZIP upload cycle on every change.

How it works

The plugins/ directory at the repository root is mounted into the backend container at /plugins. When you install a plugin from this directory, the backend creates a symlink from its internal plugin folder to your source directory instead of copying files. This means:

  • Python changes are picked up automatically by uvicorn --reload (dev mode).
  • Frontend bundle changes are served immediately from the same symlinked path.

Prerequisites

  • Docker and Docker Compose installed.
  • Run the development stack:
docker compose -f docker-compose.dev.yml up

The dev compose file mounts both ./backend and ./plugins into the backend container, enabling live reload for all Python code.

Directory structure

Place each plugin in its own subdirectory under plugins/:

plugins/
├── my-plugin/
│   ├── plugin.json       # required manifest
│   ├── main.py           # FastAPI router (optional)
│   ├── models.py         # SQLAlchemy models (optional)
│   └── frontend/
│       └── index.js      # compiled frontend bundle (optional)
└── another-plugin/
    └── plugin.json

The directory name must match the id field in plugin.json.

Installing a local plugin

  1. Log in as an admin and go to Admin → Plugins.
  2. The Local source plugins section lists every plugin found in plugins/.
  3. Click Install next to the plugin you want to activate.

The backend reads the manifest, loads the Python module, creates any database tables, and mounts the router — all without copying any files.

Making changes

Change typeWhat to do
Python (backend)Save the file — uvicorn --reload restarts automatically.
Frontend bundleRebuild the bundle inside the plugin's frontend/ directory and reload the page.
plugin.json manifestUninstall then reinstall from the admin panel to pick up new metadata.

Environment variable

The path to the local plugins directory defaults to /plugins (the docker mount point). To override it, set LOCAL_PLUGINS_DIR in the backend environment:

# docker-compose.dev.yml (already configured)
environment:
  - LOCAL_PLUGINS_DIR=/plugins

Uninstalling

Click Uninstall in the admin panel. For locally-installed plugins, only the symlink is removed — your source files in plugins/ are untouched. Database tables created by the plugin are dropped (same behaviour as ZIP-installed plugins).

Deploying a finished plugin

Once development is complete, package the plugin as a ZIP and install it via the standard Install plugin (.zip) button, or distribute the ZIP to other instances. See Authoring Plugins for the full packaging guide.