# Shared Libraries

Reuse erxes-api-shared, erxes-ui, and ui-modules


What to reuse from `erxes-api-shared`, `erxes-ui`, and `ui-modules` instead of reimplementing.

For plugin patterns, see [Backend Plugins](https://erxes.io/docs/plugin-backend) and [Frontend Plugins](https://erxes.io/docs/plugin-frontend). For how these libraries connect to services and remotes, see [Backend & API Gateway](https://erxes.io/docs/architecture-backend-gateway) and [Frontend & Plugin Loading](https://erxes.io/docs/architecture-frontend).

## Import boundaries

Every library is imported through package-name paths resolved by `paths` in [tsconfig.base.json](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/tsconfig.base.json):

```json
"paths": {
  "erxes-ui": ["frontend/libs/erxes-ui/src/index.ts"],
  "ui-modules": ["frontend/libs/ui-modules/src/index.ts"],
  "erxes-api-shared": ["backend/erxes-api-shared/src/index.ts"],
  "erxes-api-shared/*": ["backend/erxes-api-shared/src/*"]
}
```

The rule: **use only public interfaces.** Import `erxes-api-shared/utils`, `erxes-api-shared/core-types`, or `erxes-api-shared/core-modules`; never reach into a file's internals, copy shared source into a plugin, or import one service's implementation from another. Cross-service communication goes through the published GraphQL, tRPC, HTTP, and event APIs, or Module Federation exposes. Frontend plugins may not import from each other at all.

## Backend: erxes-api-shared

Location: `backend/erxes-api-shared`. Its [package.json](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/backend/erxes-api-shared/package.json) declares four Preconstruct entrypoints, which define the public API:

| Import | Contents |
| --- | --- |
| `erxes-api-shared` | Root entry; effectively empty, use the three subpath entries below |
| `erxes-api-shared/utils` | Service bootstrap and infrastructure: `startPlugin`, `joinErxesGateway`, `redis`, `mq-worker` (`sendWorkerQueue`, `createMQWorkerWithListeners`), `mongo` (connection, `createGenerateModels`, cursor utils), `apollo` (`wrapApolloResolvers`, `generateApolloContext`, pagination), `trpc`, `headers` (user/subdomain propagation), `logs` (`logHandler`, after-process), `file` (read/upload), `email`, `saas`, `sentry-init`, `graphqlPubSub`, `getEnv`, `getSubdomain`, `applyTrustProxy`, `createHealthRoute` |
| `erxes-api-shared/core-types` | Shared TypeScript types: `IMainContext`, `IPermissionConfig`, document interfaces, charge types |
| `erxes-api-shared/core-modules` | Domain modules and engines a plugin plugs into: `automations`, `segments`, `logs`, `notifications`, `properties`, `permissions`, `forms`, `apps`, `users`, `approval`, `client-portals`, `import-export`, `templates`, `common` |

The library compiles with Preconstruct (`pnpm nx build erxes-api-shared`) into `dist/` plus the `utils/`, `core-types/`, and `core-modules/` entrypoint directories, which the service Dockerfiles copy into `node_modules/erxes-api-shared`.

> [!WARNING]
> **Rebuild after every change**
>
> Services use the compiled output, not `src/`. After editing anything under `backend/erxes-api-shared/src`, run `pnpm nx build erxes-api-shared` before starting or rebuilding dependent services, or they keep running the stale build.

## Frontend: erxes-ui and ui-modules

| Library | Path | Exports |
| --- | --- | --- |
| `erxes-ui` | `frontend/libs/erxes-ui` | Design-system primitives (`components`, `lib`, `utils`), `hooks`, `state`, `types` (including `IUIConfig`), `constants`, and product building blocks under `modules/`: `board`, `record-table`, `filter`, `inputs`, `layout`, `display`, `attachments`, `record-field`, `select-tree`, `side-menu`, `preview`, `report`, `navigation-menu`, `focus-sheet`, `hotkey`, `icons`, `motion`, `blocks`, `chat-viz`, `select-operation`. Also the shared env config (`REACT_APP_API_URL`, `NODE_ENV`) the host and remotes read |
| `ui-modules` | `frontend/libs/ui-modules` | Business-domain UI under `modules/`: `contacts`, `products`, `sales`, `segments`, `tags`, `tags-new`, `automations`, `activity-logs`, `internal-notes`, `notifications`, `permissions`, `properties`, `documents`, `favorites`, `import-export`, `approval`, `brands`, `structure`, `team-members`, `templates`, `header`, `widget`, `payments`, `shared`, `types`, plus `states` (including `pluginsConfigState`) and `hooks` |

Both are Module Federation shared singletons: the host and every remote share one instance, which is why Jotai state and React context written by `ui-modules` are visible to plugin code. Use `erxes-ui` for primitives, `ui-modules` for domain composition, and `@tabler/icons-react` for icons; do not hand-roll a parallel component set.

The shared-dependency list lives in two places: [core-libraries.ts](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/core-libraries.ts) at the repository root (the canonical set, including `radix-ui`) and the `coreLibraries` copy inlined in each project's `module-federation.config.ts`. The plugin generator writes the same set into every new remote.

## Path aliases

- Frontend plugins: `~/*` → `src`, `@/*` → `src/modules`, plus `erxes-ui` and `ui-modules`.
- Backend services and plugins: `~/*` → `src`, `@/*` → `src/modules`, `erxes-api-shared/*` → the shared library source.

