# Repository Structure

Map backend, frontend, plugins, and apps in erxes/erxes


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](https://erxes.io/docs/local-setup). For the service runtime, see [Backend & API Gateway](https://erxes.io/docs/architecture-backend-gateway).

## Top-level layout

```text
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](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/backend/erxes-api-shared/src/utils/start-plugin.ts) and [service-discovery.ts](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/backend/erxes-api-shared/src/utils/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](https://erxes.io/docs/app-client-portal), [Help Center](https://erxes.io/docs/app-help-center), [POS Client](https://erxes.io/docs/app-pos-client), and [Messenger Installation](https://erxes.io/docs/erxes-messenger).

## Scripts, workers, and misc directories

- [scripts/start-api-dev.js](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/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](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/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

| File | Role |
| --- | --- |
| `package.json` | Root manifest: `dev:apis`, `dev:uis`, `dev:core-api`, `create-plugin` scripts; `packageManager: pnpm@9.12.3`; 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 |

