# Contribute to codebase

Fork, branch, validate with Nx, and open a pull request against erxes/erxes


Fork, branch, validate with Nx, and open a pull request against `erxes/erxes`. The rules your code must follow live in [Code Standards](https://erxes.io/docs/contribute-standards) and [Testing](https://erxes.io/docs/contribute-testing).

## Prerequisites

- Node.js 22 and pnpm 8 or newer; the root `package.json` pins `pnpm@9.12.3` in `packageManager` and blocks npm and Yarn through `engines`. MongoDB, Redis, and Elasticsearch 7 (only when the feature needs search) are also required.
- A working local checkout. Finish [Local Setup](https://erxes.io/docs/local-setup) before you start.
- Agreement on scope: search [existing issues](https://github.com/erxes/erxes/issues) first, and discuss large features, architectural changes, or new dependencies with maintainers before writing code. Pull requests target the `develop` branch.

### 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

```bash
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`](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/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`](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/.release-it.json) 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>`:

```bash
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](https://erxes.io/docs/contribute-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](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/.github/workflows/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.

