Contribute to OpenWA
This guide takes you from a fresh clone to a merged pull request: set up the dev environment on Node 22, find your way around the codebase, and run the same checks CI runs before you push.
Every contribution counts — a typo fix, a new endpoint, a test, a doc clarification. The conventions below keep review fast and keep main releasable.
The canonical repository is github.com/rmyndharis/OpenWA. This page targets OpenWA v0.7.6.
- Node.js 22 and npm 10+. CI builds and tests on Node 22, so match it locally to avoid surprises.
- Git and a GitHub account.
- That's all you need for a default setup — OpenWA defaults to SQLite, local-disk storage, and an in-memory cache, so no Postgres, Redis, or S3 is required to run it.
Set up your fork
Fork the repository on GitHub, then clone your fork and wire up upstream so you can pull in changes later.
# 1. Clone your fork (replace YOUR_USERNAME)
git clone https://github.com/YOUR_USERNAME/OpenWA.git
cd OpenWA
# 2. Track the canonical repo as "upstream"
git remote add upstream https://github.com/rmyndharis/OpenWA.git
# 3. Install dependencies (this also installs the dashboard's deps)
npm install
npm install runs a postinstall hook that installs the dashboard's dependencies under dashboard/, so you don't install them separately.
Run the dev server
Start the API and the dashboard together with one command:
npm run dev
This runs the NestJS API (hot-reload) and the React/Vite dashboard concurrently. On first boot the API writes a minimal config to data/.env.generated (SQLite + local storage) and generates a random admin API key in data/.api-key — so the server runs with zero manual configuration.
The API listens on port 2785 behind the global /api prefix. Confirm it's up:
curl http://localhost:2785/api/health
{
"status": "ok",
"timestamp": "2026-06-26T12:00:00.000Z",
"version": "0.7.6"
}
GET /api/health is public — it needs no API key. Every other endpoint requires the X-API-Key: YOUR_API_KEY header, where YOUR_API_KEY is the key in data/.api-key. See Configuration for the full list of environment variables.
If you don't need the dashboard, run npm run start:dev to start just the API in watch mode.
How the project is laid out
OpenWA is a NestJS API with a React/Vite dashboard and a published JavaScript SDK in one repository.
OpenWA/
├── src/ # NestJS API
│ ├── main.ts # Application entry point
│ ├── common/ # Shared cache, security, storage, errors, utils
│ ├── config/ # Env validation, bootstrap, Swagger
│ ├── core/ # Hook and plugin framework
│ ├── database/ # TypeORM data sources and migrations
│ ├── engine/ # WhatsApp engine abstraction and adapters
│ ├── modules/ # API feature modules (sessions, messages, …)
│ └── plugins/ # Built-in engine and extension plugins
├── test/ # End-to-end smoke tests
├── dashboard/ # React/Vite dashboard
├── sdk/ # JavaScript, Python, and PHP SDKs
└── docs/ # Repo documentation
Each feature module under src/modules/ maps to one of the API's resource tags — sessions, messages, webhooks, contacts, groups, labels, channels, and health. The API Reference documents every endpoint these modules expose.
A controller validates the request, calls a capability service, and the service talks to the WhatsApp engine through an adapter. Controllers stay thin: they must not import the engine interface or call getEngine() directly — an ESLint rule enforces this. Engine-specific behavior lives behind the capability services and engine adapters.
Branch and commit
Create a focused branch off main with a descriptive prefix:
git switch -c feature/add-label-filtering
| Prefix | Use for |
|---|---|
feature/ | New functionality |
bugfix/ | Bug fixes |
hotfix/ | Urgent production fixes |
docs/ | Documentation only |
refactor/ | Restructuring without behavior change |
test/ | Adding or fixing tests |
Conventional Commits
Commit messages follow Conventional Commits:
<type>(<scope>): <description>
Use one of these types: feat, fix, docs, style, refactor, perf, test, chore. The scope is the affected module or area.
feat(sessions): support multiple proxy configurations
fix(webhooks): retry delivery after a slow-connection timeout
docs(api): clarify the message-status response shape
The first line is the subject. Add a body for the "why" and a footer to link issues (Closes #123).
Run the checks CI runs
Run these locally before you open a pull request. They are the same checks CI runs, so passing here means a green build.
npm run build # NestJS build (nest build)
npm test # unit tests (Jest)
npm run lint # ESLint
npm run format # Prettier (writes changes in place)
npm run dashboard:build # dashboard type-check + build
For changes that cross module boundaries, also run the end-to-end smoke tests:
npm run test:e2e
| Command | What it does |
|---|---|
npm test | Runs all *.spec.ts unit tests with Jest. Does not collect coverage, so coverage thresholds are not enforced. |
npm run test:cov | Runs the suite with coverage and enforces the thresholds: a global floor (33% lines/statements, 30% branches/functions) plus a stricter bar for security code under src/common/security/ (90% lines/statements, 95% functions, 85% branches). |
npm run test:e2e | Boots the app and runs the end-to-end smoke tests in test/. |
npm run lint:fix | Auto-fixes lint violations where possible. |
npm test -- session.service.spec.ts | Runs a single test file. |
Add or update tests for any behavior change. Unit tests live next to the code as *.spec.ts; end-to-end smoke tests live in test/.
Code style
Prettier and ESLint enforce style — run npm run format before committing so review focuses on substance, not whitespace.
| Area | Convention |
|---|---|
| Formatting | Single quotes, 2-space indentation, 120-column width, semicolons. |
| Types | Explicit types; any is disallowed (noImplicitAny). |
| Files | kebab-case (send-message.dto.ts); classes PascalCase; functions and variables camelCase; constants UPPER_SNAKE_CASE. |
| Requests | Validate request bodies with DTOs and class-validator decorators. |
| Errors & logging | Throw NestJS HTTP exceptions; log through the project Logger (or LoggerService / createLogger), never console.*. |
Database changes
OpenWA uses TypeORM. Any change to a persisted entity needs a migration under src/database/migrations/ — do not rely on schema auto-sync.
# Generate a migration from your entity changes
npm run migration:generate --name=AddLabelColorColumn
# Apply pending migrations
npm run migration:run
Before you open a large PR
A few rules keep the project stable. Skim these before investing in a big change.
Response shapes and HTTP status codes are what users depend on. Don't change them without first opening an issue to agree on the approach. The OpenAPI spec is the source of truth.
- Keep each PR to one logical change. Smaller PRs review faster and are easier to credit and revert.
- Some message types are engine-limited. The default engine is whatsapp-web.js, which doesn't support interactive Buttons or List messages — a PR adding them won't function against the default engine. Confirm engine support before building engine-specific features.
- Discuss architecture first. For new frameworks, large rewrites, or anything touching the engine abstraction, open an issue to align before writing code.
- Update the docs and changelog. When a change is user-visible, update the relevant
docs/page and the[Unreleased]section ofCHANGELOG.md. Maintainers own version stamping and releases.
A passing CI run and a maintainer approval are required to merge.
Report a bug or request a feature
Open an issue using the Bug report or Feature request template on GitHub. The structured fields — version, deployment, engine, logs, reproduction steps — make triage far faster. Check Troubleshooting & FAQ first; many common problems are already answered there.
Do not open a public issue for a security vulnerability. Follow the private disclosure process in the repository's SECURITY.md.
Open your pull request
# Push your branch to your fork
git push -u origin feature/add-label-filtering
Then open a pull request against rmyndharis/OpenWA's main branch on GitHub. Fill in the PR template: describe the change, link related issues, and check that tests, lint, and the build pass.
By participating you agree to the project's Community Guidelines and Code of Conduct. Contributions are licensed under the project's MIT License.
Next steps
- Quick start — run OpenWA end to end before changing it.
- API conventions — the auth, error envelope, and status codes your changes must respect.
- API reference — the generated spec, the contract every endpoint change is measured against.