Demo

Creating a plugin

End-to-end recipe: scaffold with @quan-erp/cli, align names and @quan-erp/* versions, add a first feature, watch into available-plugins, then install on the running base stack.

Goal

Produce a working plugin folder under plugins/ that builds, installs, and registers menus/routes in the Quark ERP shell.

  • One folder: module.metadata.json + backend/ + frontend/
  • Folder name === metadata.name === package identity
  • Artifacts land in available-plugins, then installed-plugins after Install

1. Prerequisites

You need a Quark ERP project and a running base stack before scaffolding.

  • Project created with quan-erp new-project (see Installation)
  • @quan-erp/cli installed: npm i -g @quan-erp/cli
  • Base stack up: quan-erp base:dev
  • Node.js 18+ (20+ LTS recommended)
  • Pick a lowercase kebab-case name (e.g. fleet-management, hr, inventory)
TSQuick check
quan-erp help quan-erp base:dev # if base is not already up

2. Scaffold the plugin

Use the CLI for a clean empty plugin. Copy sample-es when you want working menus, pages, and API patterns to edit.

  • quan-erp new / new-plugin — interactive; good for greenfield plugins
  • sample-es — best reference for IPlugin, register(AppRegistry), api/, page/
  • Keep the top-level layout: backend/ + frontend/ + module.metadata.json
TSOption A — quan-erp new
1# From project root 2quan-erp new 3# or: quan-erp new-plugin 4# optional: quan-erp new-plugin --version latest 5# Prompts: name, description, module entry object, version 6# Creates plugins/<name>/{backend,frontend,module.metadata.json}
TSOption B — copy sample-es
cp -R plugins/sample-es plugins/my-plugin # Then rename packages + metadata.name (next section)

3. Align names (critical)

If these strings disagree, watch, install, and DI fail in confusing ways. Verify after every scaffold.

  • name — unique plugin id for API prefixes, menus, and @Inject scope
  • pluginVersion — folder under available-plugins/<name>/<version>/
  • requiredBasedVersion — must match the base / @quan-erp/* line
  • moduleEntryObject — root @Module class name (usually Module)
  • pluginDependencies — plugins that must load first (add when you consume exports)
TSIdentity checklist
1plugins/<name>/ # folder 2module.metadata.json → "name": "<name>" 3backend/package.json → "@quan-erp-plugins/<name>-backend" 4frontend/package.json → "@quan-erp-plugins/<name>-frontend" 5@Module({ name: metadata.name, ... }) # backend root module
JSONmodule.metadata.json
1{ 2 "name": "my-plugin", 3 "type": "", 4 "pluginVersion": "1.0.0", 5 "description": "My first plugin", 6 "moduleEntryObject": "Module", 7 "requiredBasedVersion": "1.0.0", 8 "pluginDependencies": {} 9}

4. Align @quan-erp/* versions

Backend and frontend @quan-erp/* dependencies must match the base images / BASE_VERSION.

  • Copy version pins from sample-es or another working plugin on the same base
  • Reinstall deps in plugins/<name>/backend and frontend after version changes
  • Rebuild with quan-erp watch after dependency changes
SHInstall deps
cd plugins/my-plugin/backend && npm install cd ../frontend && npm install cd ../../.. # back to project root

5. Add your first feature

Keep the first change small: one entity + service + controller on the backend, one page + api hook + menu/route on the frontend.

  • Backend — backend/src/index.ts (IPlugin), feature folder, schema/*.entity.ts, register on root @Module
  • Frontend — frontend/src/index.tsx register(AppRegistry): setAxiosClient, menu.add, route.add
  • API layer — frontend/src/api/<domain>/ with React Query; pages import hooks only
  • Namespace tables and HTTP paths with the plugin name
  • Do not import another plugin’s src/ — use Export / expose APIs later

6. Build with quan-erp watch

From the project root, watch compiles backend + frontend into base/available-plugins/<name>/<version>/.

  • Argument is the folder name under plugins/
  • Confirm available-plugins/my-plugin/<version>/ has backend/, frontend/, module.metadata.json
  • If already installed, watch also refreshes the installed copy during development
TSTerminal
quan-erp watch my-plugin # one-shot production build quan-erp build:prod my-plugin

7. Install in the ERP UI

Watch only stages available-plugins. The shell loads installed-plugins. Install from the Modules UI (or your local seed + install flow).

  • Open Modules in the running ERP and Install your plugin
  • Confirm base/backend/installed-plugins/<name>/ exists
  • Hard-refresh the browser; look for menus/routes from register()
  • If nothing appears — see Troubleshooting → Plugins installed but frontend not loaded