Repository Structure
Find any project in erxes/erxes: backend services, plugin projects, frontend remotes, shared libraries, standalone apps, and the config files that tie them together.
For running the product from source, use Local Setup. For the service runtime, see Backend & API Gateway.
Top-level layout
erxes/
├── backend/
│ ├── core-api/ Core business logic (port 3300)
│ ├── gateway/ API gateway + Apollo Router (port 4000)
│ ├── erxes-api-shared/ Shared library for all services
│ ├── plugins/ Plugin microservices (*_api, ports 3303+)
│ ├── services/ Background services (automations, logs)
│ └── saas-migrations/ Standalone one-off migration scripts
├── frontend/
│ ├── core-ui/ Module Federation host (port 3001)
│ ├── libs/ erxes-ui + ui-modules shared UI
│ └── plugins/ Frontend remotes (*_ui, ports 3002-3011)
├── apps/ Standalone apps (not started by dev:apis/dev:uis)
├── cloudflare/mail-worker/ Cloudflare Worker for inbound email routing
├── docs/ Scattered product notes (not the docs site)
├── scripts/ Dev scripts and plugin generators
└── .github/workflows/ CI image builds per service/app
The root also carries package.json, pnpm-workspace.yaml, nx.json, tsconfig.base.json, tsconfig.json, migrations.json, core-libraries.ts, .env.sample, eslint.config.js, jest.config.ts, index.html, CONTRIBUTING.md, and LICENSE.md. There is no root docker-compose.yml; each deployable project has its own Dockerfile.
Backend
| Path | Nx project | Dev port | Purpose |
|---|---|---|---|
backend/gateway | gateway | 4000 (PORT) | Express gateway; proxies /graphql to the internal Apollo Router on 50000 (APOLLO_ROUTER_PORT) |
backend/core-api | core-api | 3300 (PORT) | Core business modules, GraphQL subgraph, tRPC router |
backend/erxes-api-shared | erxes-api-shared | n/a | Shared library; build it before serving APIs |
backend/services/automations | automations-service | 3302 (PORT) | Automation execution workers |
backend/services/logs | logs-service | 3301 (PORT) | Persisted logs and the undo journal |
backend/saas-migrations | n/a | n/a | Standalone migration scripts grouped by domain |
backend/core-api/src/ holds apollo/ (schema and resolvers), modules/ (business domains such as contacts, products, segments, automations, documents), meta/, trpc wiring in init-trpc.ts, routes/, connectionResolvers.ts, and main.ts. backend/gateway/src/ holds apollo-router/ (router download, supergraph compose, spawn/recovery), proxy/ (service proxying, including /pl:<serviceName> routes), middlewares/, mq/, subscription/, and locales/.
backend/erxes-api-shared is a multi-entry package built with preconstruct: src/utils/ (service discovery, Redis, tRPC, startPlugin), src/core-modules/ (reusable domain logic), src/core-types/, and src/common-modules/ compile to utils/, core-modules/, core-types/ entry points.
Backend plugins
Each backend/plugins/<name>_api starts through startPlugin({ name, port, ... }) in src/main.ts and registers with the gateway via Redis service discovery (see start-plugin.ts and service-discovery.ts). Ports below come from each plugin's src/main.ts.
| Plugin project | Plugin name | Dev port |
|---|---|---|
content_api | content | 3303 |
frontline_api | frontline | 3304 |
operation_api | operation | 3307 |
posclient_api | posclient | 3312 |
sales_api | sales | 3305 |
A backend plugin typically contains src/main.ts, src/connectionResolvers.ts, src/apollo/ (typeDefs/resolvers), src/modules/, src/trpc/ or init-trpc.ts, src/meta/, plus project.json, Dockerfile, and package.json.
Frontend
| Path | Nx project | Dev port | Purpose |
|---|---|---|---|
frontend/core-ui | core-ui | 3001 | Module Federation host; browser entry point |
frontend/libs/erxes-ui | erxes-ui | n/a | Core UI primitives, hooks, state, config |
frontend/libs/ui-modules | ui-modules | n/a | Reusable business-domain UI modules |
frontend/core-ui/src/ holds main.ts, bootstrap.tsx (renders directly in development; fetches /get-frontend-plugins and initializes remotes in production), modules/, pages/, plugins/, providers/, and i18n/. module-federation.config.ts maps ENABLED_PLUGINS to <name>_ui remotes and shares a fixed set of libraries (react, react-router, erxes-ui, ui-modules, jotai, @apollo/client, react-i18next) as singletons.
Frontend plugins
Each frontend/plugins/<name>_ui is a Module Federation remote served by Rspack. Ports below come from each plugin's project.json serve target.
| Plugin project | Dev port |
|---|---|
content_ui | 3003 |
frontline_ui | 3004 |
operation_ui | 3006 |
sales_ui | 3005 |
A frontend plugin typically contains src/config.tsx (routes, navigation, remote registration), src/modules/, src/pages/, src/widgets/, src/main.ts, src/bootstrap.tsx, module-federation.config.ts, rspack.config.ts, and project.json.
There is no posclient_ui; the POS frontend is the standalone app apps/posclient-front.
Apps
Standalone apps under apps/ have their own dependencies and scripts. They are not part of pnpm dev:apis or pnpm dev:uis.
| App | Stack | Dev command/port |
|---|---|---|
apps/client-portal-template | Next.js 16.0.3, React 19 | next dev --port 3800 |
apps/help-center | Next.js 16.3.2, React 19 | next dev --port 3900 |
apps/posclient-front | Next.js 14, React 18, PWA | next dev -p 7002 |
apps/frontline-widgets | Rspack bundles (chat, forms) | nx dev frontline-widgets (serve + bundle watchers) |
See Client Portal, Help Center, POS Client, and Messenger Installation.
Scripts, workers, and misc directories
- scripts/start-api-dev.js maps
ENABLED_PLUGINSandENABLED_PLUGINS_ONLY_APIto*_apiprojects andENABLED_SERVICESto*-serviceprojects, then runsnx run-many -t serve -p core-api ... gateway. - scripts/start-ui-dev.js maps
ENABLED_PLUGINSto*_uiremotes vianx serve core-ui --devRemotes. scripts/create-plugin.jsscaffolds a paired*_api+*_uiplugin (pnpm create-plugin);scripts/create-backend-plugin.jsscaffolds the backend half only.cloudflare/mail-workeris a standalone Cloudflare Worker (ownpackage-lock.json,wrangler.toml) that routes inbound email to the frontline plugin's/mail/receivewebhook; the relatedMAIL_*variables are documented in.env.sample.docs/contains isolated product notes, not the public documentation site.
Root configuration files
| File | Role |
|---|---|
package.json | Root manifest: dev:apis, dev:uis, dev:core-api, create-plugin scripts; packageManager: [email protected]; pnpm overrides |
pnpm-workspace.yaml | Workspace packages: backend/**, frontend/** (apps install separately) |
nx.json | Named inputs, Nx plugins (eslint, jest, webpack, storybook), target defaults, generator defaults (Rspack + Tailwind) |
tsconfig.base.json | Base compiler options and the shared path aliases below |
tsconfig.json | Solution-style file that references every project's tsconfig |
migrations.json | Nx migration entries recorded during past nx migrate runs |
core-libraries.ts | A shared-library name set (adds radix-ui); nothing imports it, so each module-federation.config.ts declares its own list |
.env.sample | Commented environment template |
eslint.config.js, jest.config.ts, jest.preset.js | Lint and test defaults |
index.html | Static messenger-widget test page |
Path aliases
tsconfig.base.json declares the shared aliases; each project adds local ones in its own tsconfig.json.
| Alias | Resolves to | Where |
|---|---|---|
erxes-ui | frontend/libs/erxes-ui/src/index.ts | Root tsconfig.base.json |
ui-modules | frontend/libs/ui-modules/src/index.ts | Root tsconfig.base.json |
erxes-api-shared, erxes-api-shared/* | backend/erxes-api-shared/src/index.ts, backend/erxes-api-shared/src/* | Root tsconfig.base.json |
~/* | <project>/src/* | Each backend service and frontend plugin tsconfig |
@/* | <project>/src/modules/* | Each backend service and frontend plugin tsconfig |