Build Plugins
Extend erxes with your own backend services and frontend remotes, from pnpm create-plugin to a deployed, permission-aware feature.
Plugin anatomy
A complete plugin is a pair of Nx projects:
backend/plugins/<name>_api Express service: subgraph /graphql, /trpc router,
meta extension hooks, BullMQ workers, one port each
frontend/plugins/<name>_ui Module Federation remote: ./config plus module,
settings, and widget exposes
The _api service calls startPlugin({ name, port, ... }) from erxes-api-shared (start-plugin.ts) and registers with the gateway through Redis service discovery. The gateway composes its subgraph once the service answers _service { sdl }.
The _ui remote exposes ./config, an IUIConfig object the core-ui host loads to build navigation, routes, settings entries, and widgets. Enable both at once by adding the base name (inventory, not inventory_api) to ENABLED_PLUGINS.
The scope boundary
erxes enforces a hard plugin boundary:
- A backend-only task may write only under
backend/plugins/<name>_api/**; a frontend-only task only underfrontend/plugins/<name>_ui/**; a full-stack plugin task only under those two matching directories. - Never edit
core-api,core-ui, another plugin, a shared library, or root infrastructure to make a plugin feature work, and never import another plugin's source, models, state, or components. - Use shared code only through the public APIs of
erxes-api-shared,erxes-ui, andui-modules. If the behavior cannot be implemented inside the boundary, stop and report the missing platform capability; a core or shared change is a separate task with explicit scope.
Guides
Start with Create a Plugin, then read the generated code alongside Backend Plugins and Frontend Plugins. For the core modules your meta hooks and tRPC calls target, see Core Platform; for how plugins register and load, see Architecture.