erxes: a monorepo that says five core modules and then lists six
Experience Operating System (XOS) that unifies marketing, sales, operations, and support — run your core business seamlessly while replacing HubSpot, Zendesk, Linear, Wix and more.
At a glance
- What is it?
- erxes is a self-hosted experience management platform built as an Nx monorepo with a core and a set of plugins, each plugin carrying its own API and UI service. Its readme describes the core as five modules and then names six, the manifest declares MIT while nothing in the repository metadata resolves, and the last line of the readme breaks off mid-word.
- Who is it for?
- erxes suits an agency or SaaS provider that wants one installable platform instead of a stack of separate tools, and that can commit to pnpm, since the manifest makes using anything else fail deliberately. Read the plugin marketplace before installing, since the value of the system is the plugin set rather than the core.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The core is described as five modules and then six are named
The section on core and plugins says erxes is composed of two main components, Core and Plugins, and that the core contains the core five modules which go with all plugins.
Then it names them: My inbox, Contacts, Products, Segments, Automation, Documents.
That is six. The number in the prose does not match the list that follows it, and the list is the one that would be used to work out what a plugin can rely on being present.
The distinction between the two halves is what matters more than the count. Core is the part every plugin gets, which is why the shared surface has to be right: a plugin that stores a contact reference or queues an automation action is depending on those modules existing with a stable shape. Plugins are the part you choose, nine of which are listed by name.
So the sentence about five modules is a small error in the most structurally important sentence in the readme.
pnpm is enforced by making the other package managers fail
The prerequisites say pnpm 8 or newer is required, and the install block repeats it with a comment saying dependencies must use pnpm.
The manifest enforces that rather than asking for it. Its engines block declares `pnpm` as `>=8`, and then sets the other two to strings that are not version constraints at all: `npm` is `please-use-pnpm` and `yarn` is `please-use-pnpm`. A version field holding a sentence is not a version range, so an install driven by npm or yarn is meant to fail rather than quietly work.
The technology stack table gives a second, conflicting number, listing pnpm 9.12 in the build row alongside Nx 20.0 and Docker. So the prerequisites say 8 or newer and the stack table names 9.12.
The manifest also sets `private: true`, which is what makes the engines block effective. The package is never published, so the field is only read by the tool doing the install, which is exactly the tool the block is aimed at.
Every update and delete is journalled, with no flag to turn it off
The environment sample documents a point-in-time revert feature in more detail than anything else in the repository. Every update or delete made through any model is journaled to a `{subdomain}_logs` collection so it can be reverted later, reachable in the interface as System Logs then Undo.
The boundaries are stated precisely. Creates are not captured, on the grounds that reverting a new record is just deleting it. Capture is always on, with no enable flag, and it runs from boot on every service that writes through the shared API layer, which the comment names as the core API and plugins. The logs service must also be running for entries to persist at all.
The one tunable is a per-write snapshot cap, `REVERT_AUTO_JOURNAL_MAX`, defaulting to 1000. Past that cap the ids are still audited but the overflow is not automatically revertable.
So the undo capability has a real cost and a real limit, both written down. A bulk delete of more than a thousand documents leaves you with an audit trail and no one-click restore for the tail of it.
The licence is MIT in the manifest and unasserted in the repository metadata
There are three statements about licensing and they do not agree.
The manifest has a license field set to MIT. The readme links to a `LICENSE.md` file in the repository root using a link that points at `master`, while the default branch is `main`. And the repository metadata as published records the licence as unasserted rather than as MIT, which is what happens when the licence file is not recognised in its current form.
The readme also describes erxes as source available rather than open source, in the bullet about being free and sustainable, and phrases it as source available software, but even better. Those are not the same category as the MIT grant the manifest states, and the readme does not reconcile them.
For a platform whose selling point includes self-hosting and data staying in your own infrastructure, this matters more than it would for a library. Open the licence file yourself before you build a business process on it, and note that the badge link in the readme points at a branch name that is not the default one.
Two ports in the diagram and a third in the quick start
The install sequence is seven steps, and two of them are the ones people get wrong. First, the sample environment file, which the readme calls `.env.example`:
# Clone the repository
git clone https://github.com/erxes/erxes.git
cd erxes
# Install dependencies (must use pnpm)
pnpm install
# Set up environment variables
cp .env.example .env
# Edit .env and configure MONGO_URL, REDIS_HOST, etc.
# Start core services (Gateway + Core API)
pnpm dev:core-api
# Or start all APIs
pnpm dev:apis
# Start all UI plugins (in another terminal)
pnpm dev:uisThe architecture section gives an ASCII diagram with the gateway on port 4000, described as Apollo Router with service discovery, fanning out to a Core API on port 3300 and to plugin APIs whose ports are not named.
The quick start then tells you to access the application at `http://localhost:3001`, and the sample environment file has a commented line for the API URL pointing at port 4000. So three ports appear across the readme: 4000 for the gateway, 3300 for the core API, and 3001 for the interface.
That split is what a micro frontend architecture looks like from the outside. The backend is a federated graph behind one router, and each plugin contributes both an API and a UI, which is why the dev scripts come in pairs: `dev:core-api` starts the core API and the gateway, while `dev:apis` and `dev:uis` start the plugin services through Node scripts that read the environment file with dotenv.
The Nx commands are the per service path. You can serve, build and test one project by name, and there is also an affected pair, `affected:build` and `affected:test`, which run only what a change touches.
Four agent instruction files and a committed pnpm store
The root of the repository contains `AGENTS.md`, `CLAUDE.md`, `GEMINI.md` and `.cursorrules`, plus an `.opencode/` directory. Four of those are instruction files for coding assistants and one is a configuration directory for another tool.
For a project where an automated contributor is a realistic part of the workflow, having the conventions written once per tool is a deliberate choice rather than redundancy, since each of those tools reads its own file and none of them reads the others.
Two other root entries are more unusual. `.pnpm-store/` is a package store directory in the repository, which normally belongs in a gitignore rather than in version control. And `MERGE_FK_TASK.md` sits among the project documentation files with a name that suggests a specific piece of work rather than a topic.
Then there is the tooling surface: `nx.json`, `pnpm-workspace.yaml`, `tsconfig.base.json`, `eslint.config.js`, `.prettierrc`, `jest.config.ts` with a preset file, `migrations.json`, `.sentryclirc`, `.deepsource.toml`, `HACKTOBERFEST.md`, `SECURITY.md`, `AGENTS.md` and a `cloudflare/` directory.
There is also `.env.sample` alongside a second sample referenced in the install block as `.env.example`, which are two names for what looks like one file.
The readme's last sentence is cut off mid-word
The documentation section lists five links: the official documentation, a local setup guide, a contributing guide, a roadmap and a changelog. Each is a page on the project website rather than a file in the repository, with the exception of nothing.
Then the final line of the readme is this: we recommend always using the latest version of erxe.
The word is cut off mid-word. What follows is not in the file.
Given the release cadence that is not a small omission. The three most recent releases are v3.2.10 on 1 October 2026, v3.2.11 the same day at a later hour, and v3.2.12 on 4 October 2026, and the manifest version field reads 3.2.12. So the recommendation to use the latest version is well founded and also the sentence that tells you nothing about how to pin, upgrade or verify a version.
The roadmap and changelog being website pages means the release history that would answer that is not in the repository either, even though `CHANGELOG.md` sits in the root.
Editorial conclusion
erxes suits an agency or SaaS provider that wants one installable platform instead of a stack of separate tools, and that can commit to pnpm, since the manifest makes using anything else fail deliberately. Read the plugin marketplace before installing, since the value of the system is the plugin set rather than the core. Set your expectations on the undo feature by reading the environment sample: the journal captures updates and deletes only, is always on with no flag, and needs the logs service running to persist. And check the licence file yourself, because the manifest and the repository metadata disagree about what it is.
Frequently asked questions
what is erxes
erxes is a secure, self-hosted, scalable experience management infrastructure, described as an Experience Operating System, for SaaS providers and digital marketing agencies. It is an Nx-powered monorepo with a core of shared modules and a set of plugins chosen from a marketplace, where each plugin brings its own API and UI service.
how to install erxes locally
Clone the repository, install with pnpm, copy the sample environment file to `.env`, and configure MONGO_URL and REDIS_HOST among the other variables. Then run `pnpm dev:core-api` for the gateway and core API, or `pnpm dev:apis`, with `pnpm dev:uis` in another terminal, and open http://localhost:3001. Prerequisites are Node.js 18 or newer, pnpm 8 or newer, MongoDB and Redis.
can erxes undo an accidental delete
Yes, for updates and deletes made through the models. Every such write is journaled so it can be reverted from System Logs then Undo, and the capture is always on with no enable flag. Creates are not captured, and the logs service has to be running for entries to persist. There is a per-write snapshot cap, REVERT_AUTO_JOURNAL_MAX, defaulting to 1000.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/erxes-erxes)