Skip to content

Plugin System Guide

This guide explains how to extend Business M by creating and integrating new domain plugins.

A backend plugin is a standard Framework M App defined as a library.

libs/my_plugin/
β”œβ”€β”€ src/
β”‚ └── my_plugin/
β”‚ β”œβ”€β”€ __init__.py # App definition
β”‚ β”œβ”€β”€ doctypes/ # Domain entities
β”‚ β”œβ”€β”€ services/ # Business logic
β”‚ └── bootstrap.py # DI wiring & extensions
β”œβ”€β”€ pyproject.toml
└── README.md

In pyproject.toml, register the app and optional bootstrap/container:

[project.entry-points."framework_m.apps"]
my_plugin = "my_plugin:app"
[project.entry-points."framework_m.bootstrap"]
my_plugin_init = "my_plugin.bootstrap:MyPluginBootstrap"

Use the Bounded Context pattern. Instead of adding fields directly to core Item, create a MyPluginItem in your library:

class MyPluginItem(BaseDocType):
item: str = Field(description="Link to core Item")
special_field: str = Field(...)
class Meta:
table_name = "my_plugin_item"

Frontend plugins are integrated into the Desk UI at build-time.

libs/my_plugin/frontend/
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ pages/
β”‚ β”œβ”€β”€ components/
β”‚ └── plugin.config.ts # Plugin Manifest
β”œβ”€β”€ package.json
└── vite.config.ts

The manifest defines how your plugin integrates into the UI:

import type { FrameworkMPlugin } from "@framework-m/plugin-sdk";
const plugin: FrameworkMPlugin = {
name: "my_plugin",
version: "0.1.0",
manifests: [
{
app_id: "my_plugin",
label: "My Plugin",
icon: "box",
resources: [
{
name: "my_plugin.dashboard",
label: "Dashboard",
route: "/my-plugin/dashboard",
}
]
}
],
routes: [
{
path: "/my-plugin/dashboard",
element: () => import("./pages/Dashboard"),
}
]
};
export default plugin;

To enable your plugin in the main application:

Add the library to apps/business-m/pyproject.toml or install it in the environment.

Terminal window
cd apps/business-m
uv add --path ../../libs/my_plugin

Add the plugin path to apps/business-m/frontend/plugin.config.ts (or the discovery configuration). Ensure the library is linked via pnpm:

Terminal window
cd apps/business-m/frontend
pnpm add ../../../libs/my_plugin/frontend
  • Namespacing: Always prefix your DocTypes and menu items to avoid collisions (e.g., my_plugin.settings).
  • Isolation: Use m_protocols to communicate with other libraries. Avoid direct imports of other domain logic.
  • Seeding: Use m seed to populate initial data required by your plugin.