Shared Libraries
What to reuse from erxes-api-shared, erxes-ui, and ui-modules instead of reimplementing.
For plugin patterns, see Backend Plugins and Frontend Plugins. For how these libraries connect to services and remotes, see Backend & API Gateway and Frontend & Plugin Loading.
Import boundaries
Every library is imported through package-name paths resolved by paths in tsconfig.base.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 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.
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 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, pluserxes-uiandui-modules. - Backend services and plugins:
~/*→src,@/*→src/modules,erxes-api-shared/*→ the shared library source.