Contribute to codebase
Fork, branch, validate with Nx, and open a pull request against erxes/erxes. The rules your code must follow live in Code Standards and Testing.
Prerequisites
- Node.js 22 and pnpm 8 or newer; the root
package.jsonpins[email protected]inpackageManagerand blocks npm and Yarn throughengines. MongoDB, Redis, and Elasticsearch 7 (only when the feature needs search) are also required. - A working local checkout. Finish Local Setup before you start.
- Agreement on scope: search existing issues first, and discuss large features, architectural changes, or new dependencies with maintainers before writing code. Pull requests target the
developbranch.
1. Pick an issue and find the project to change
Choose an existing issue or open one with the current behavior, expected behavior, and reproduction context. Keep one pull request to one issue or one cohesive outcome.
Then identify which Nx project holds the change: backend/plugins/<name>_api for a backend plugin, frontend/plugins/<name>_ui for its frontend, backend/core-api / frontend/core-ui for core work. Do not move logic into a shared library or another plugin because it is convenient.
2. Fork, clone, and branch from develop
git clone https://github.com/<your-github-username>/erxes.git
cd erxes
git remote add upstream https://github.com/erxes/erxes.git
git fetch upstream
git switch develop
git pull --ff-only upstream develop
git switch -c fix/deal-stage-filter
pnpm install
CONTRIBUTING.md requires the branch prefixes feat/ (features), fix/ (bug fixes), and docs/ (documentation), followed by a short description such as fix/deal-stage-filter.
3. Read the local conventions
Each directory's AGENTS.md describes its local conventions; read the ones on the path to the files you will change. Plugin guides live at the root of backend/plugins/<name>_api/ and frontend/plugins/<name>_ui/; read the guide for the plugin in scope, not every plugin's. The closest file governs local details, and local rules never weaken the plugin scope boundary, security, or tenant isolation.
4. Stay inside the plugin scope boundary
A backend-only task may write only under backend/plugins/<name>_api/**; a frontend-only task only under frontend/plugins/<name>_ui/**; a full-stack plugin task only under those two directories. Never edit core-api, core-ui, another plugin, a shared library, or root infrastructure to make a plugin feature work, and never import another plugin's source. Use shared code only through the public APIs of erxes-ui, ui-modules, or erxes-api-shared. If the behavior cannot be built inside the boundary, stop and report the missing platform capability instead of widening the diff.
5. Implement, then commit
Search for a similar implementation in the same project first and reuse its components, hooks, GraphQL documents, model conventions, and error handling. Deliver complete behavior: no placeholder pages, inactive buttons, forms without validation, lists without loading or empty states, or mutations without feedback.
CONTRIBUTING.md does not enforce a commit-message format, but the history follows conventional commits: feat(scope): ..., fix(scope): ..., occasionally release X.Y.Z (written by release-it). Match that pattern. release-it generates CHANGELOG.md from conventional messages via @release-it/conventional-changelog, so scoped messages feed the published changelog. Keep commits small and coherent, and reference the issue number.
6. Run the required checks locally
Run the targets the changed project defines; inspect project.json or pnpm nx show project <name>:
pnpm nx lint sales_ui
pnpm nx build sales_ui
pnpm nx test sales_ui # only when a test target exists
pnpm nx affected -t lint,build,test # for changes spanning projects
When you change erxes-api-shared, rebuild it before validating consumers: pnpm nx build erxes-api-shared. content_api defines no Nx lint or test target; it has its own validation commands, covered in Testing.
On your pull request, the per-area workflows (CI plugin--<name>_api, CI plugin--<name>_ui, core-ui-ci, CI Gateway, CI migrations, plus CodeQL on PRs to main and develop; see ci-api-core.yml) install dependencies and build the affected project. Docker pushes and R2 syncs are gated to pushes on main and tags, so a PR gets build checks, not publishes.
7. Open the pull request
Open the PR against develop, link the issue, and include what changed, why, how, the verification commands you ran, screenshots or recordings for visible UI changes, and migration or deployment notes when operators must act. Rebase and resolve conflicts locally before requesting review. Pull requests are squash-merged, and maintainers create releases from the integration branches; contributors do not update release metadata.