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

PathNx projectDev portPurpose
backend/gatewaygateway4000 (PORT)Express gateway; proxies /graphql to the internal Apollo Router on 50000 (APOLLO_ROUTER_PORT)
backend/core-apicore-api3300 (PORT)Core business modules, GraphQL subgraph, tRPC router
backend/erxes-api-sharederxes-api-sharedn/aShared library; build it before serving APIs
backend/services/automationsautomations-service3302 (PORT)Automation execution workers
backend/services/logslogs-service3301 (PORT)Persisted logs and the undo journal
backend/saas-migrationsn/an/aStandalone 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 projectPlugin nameDev port
content_apicontent3303
frontline_apifrontline3304
operation_apioperation3307
posclient_apiposclient3312
sales_apisales3305

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

PathNx projectDev portPurpose
frontend/core-uicore-ui3001Module Federation host; browser entry point
frontend/libs/erxes-uierxes-uin/aCore UI primitives, hooks, state, config
frontend/libs/ui-modulesui-modulesn/aReusable 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 projectDev port
content_ui3003
frontline_ui3004
operation_ui3006
sales_ui3005

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.

AppStackDev command/port
apps/client-portal-templateNext.js 16.0.3, React 19next dev --port 3800
apps/help-centerNext.js 16.3.2, React 19next dev --port 3900
apps/posclient-frontNext.js 14, React 18, PWAnext dev -p 7002
apps/frontline-widgetsRspack 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_PLUGINS and ENABLED_PLUGINS_ONLY_API to *_api projects and ENABLED_SERVICES to *-service projects, then runs nx run-many -t serve -p core-api ... gateway.
  • scripts/start-ui-dev.js maps ENABLED_PLUGINS to *_ui remotes via nx serve core-ui --devRemotes.
  • scripts/create-plugin.js scaffolds a paired *_api + *_ui plugin (pnpm create-plugin); scripts/create-backend-plugin.js scaffolds the backend half only.
  • cloudflare/mail-worker is a standalone Cloudflare Worker (own package-lock.json, wrangler.toml) that routes inbound email to the frontline plugin's /mail/receive webhook; the related MAIL_* variables are documented in .env.sample.
  • docs/ contains isolated product notes, not the public documentation site.

Root configuration files

FileRole
package.jsonRoot manifest: dev:apis, dev:uis, dev:core-api, create-plugin scripts; packageManager: [email protected]; pnpm overrides
pnpm-workspace.yamlWorkspace packages: backend/**, frontend/** (apps install separately)
nx.jsonNamed inputs, Nx plugins (eslint, jest, webpack, storybook), target defaults, generator defaults (Rspack + Tailwind)
tsconfig.base.jsonBase compiler options and the shared path aliases below
tsconfig.jsonSolution-style file that references every project's tsconfig
migrations.jsonNx migration entries recorded during past nx migrate runs
core-libraries.tsA shared-library name set (adds radix-ui); nothing imports it, so each module-federation.config.ts declares its own list
.env.sampleCommented environment template
eslint.config.js, jest.config.ts, jest.preset.jsLint and test defaults
index.htmlStatic messenger-widget test page

Path aliases

tsconfig.base.json declares the shared aliases; each project adds local ones in its own tsconfig.json.

AliasResolves toWhere
erxes-uifrontend/libs/erxes-ui/src/index.tsRoot tsconfig.base.json
ui-modulesfrontend/libs/ui-modules/src/index.tsRoot 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
Was this helpful?