Thank you for your interest in contributing to WAMR (WhatsApp Media Request Manager)! We welcome contributions from the community and are excited to have you on board.
- Code of Conduct
- How Can I Contribute?
- Getting Started
- Development Workflow
- Coding Conventions
- Commit Message Guidelines
- Pull Request Process
- Issue Guidelines
- Testing Guidelines
This project and everyone participating in it is governed by our Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to the project maintainers.
Before creating bug reports, please check the existing issues to avoid duplicates. When you create a bug report, include as many details as possible:
- Use a clear and descriptive title
- Describe the exact steps to reproduce the problem
- Provide specific examples to demonstrate the steps
- Describe the behavior you observed and what you expected
- Include screenshots or animated GIFs if applicable
- Include your environment details (OS, Node version, etc.)
Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion:
- Use a clear and descriptive title
- Provide a detailed description of the suggested enhancement
- Explain why this enhancement would be useful
- List any alternative solutions you've considered
Unsure where to begin? Look for issues labeled:
good first issue- Simple issues suitable for beginnershelp wanted- Issues where we'd appreciate community helpdocumentation- Documentation improvements
We actively welcome your pull requests! Here's how to contribute code:
- Fork the repo and create your branch from
main - If you've added code that should be tested, add tests
- Ensure the test suite passes
- Make sure your code lints
- Issue that pull request!
- Node.js >= 20.0.0
- npm >= 10.0.0
- Git
-
Fork and clone the repository
git clone https://github.com/YOUR_USERNAME/wamr.git cd wamr -
Install dependencies
npm install
-
Configure environment variables
# Backend cd backend cp .env.example .env # Edit .env with your configuration # Frontend cd ../frontend cp .env.example .env # Edit .env with your configuration
-
Generate security keys
# JWT Secret openssl rand -base64 32 # Encryption Key openssl rand -hex 32
-
Setup database
cd backend npm run db:generate npm run db:migrate npm run db:seed -
Start development servers
cd .. npm run dev
main- Production-ready codedevelop- Integration branch for features (if used)feature/*- New featuresbugfix/*- Bug fixeshotfix/*- Urgent production fixesdocs/*- Documentation updates
git checkout main
git pull origin main
git checkout -b feature/your-feature-name- Make your changes in the feature branch
- Follow the coding conventions
- Write or update tests as needed
- Ensure all tests pass:
npm run test - Ensure code lints:
npm run lint - Format your code:
npm run format
We follow the Conventional Commits specification:
git add .
git commit -m "feat: add new feature"See Commit Message Guidelines for details.
- Use TypeScript for all new code
- Define types explicitly rather than using
any - Use interfaces for object shapes
- Use type aliases for unions and complex types
- Export types from dedicated
types/files
We use ESLint and Prettier to maintain consistent code style:
# Check linting
npm run lint
# Fix linting issues
npm run lint:fix
# Format code
npm run format
# Check formatting
npm run format:checkKey conventions:
- Use 2 spaces for indentation
- Use single quotes for strings
- Use semicolons
- Use trailing commas in multi-line objects/arrays
- Use arrow functions over function expressions
- Use
constoverletwhen possible - Avoid
var
- Group related functionality in modules
- Keep files focused and under 300 lines when possible
- Use index files to export public APIs
- Place tests alongside the code they test
- Files:
kebab-case.ts - Components:
PascalCase.tsx - Variables/Functions:
camelCase - Constants:
UPPER_SNAKE_CASE - Types/Interfaces:
PascalCase - Private members: prefix with
_
- Use dependency injection where appropriate
- Separate concerns: routes → controllers → services → repositories
- Validate all inputs using Zod schemas
- Use proper error handling with custom error codes
- Log important events using the provided logger
- Never log sensitive information (passwords, tokens, etc.)
- Use functional components with hooks
- Keep components small and focused
- Use custom hooks for reusable logic
- Use React Query for server state
- Use Zustand for client state
- Follow the component structure:
// Imports // Types // Component // Exports
We follow the Conventional Commits specification:
<type>(<scope>): <subject>
<body>
<footer>
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, semicolons, etc.)refactor: Code refactoring (no functional changes)perf: Performance improvementstest: Adding or updating testschore: Maintenance tasks (dependencies, build, etc.)ci: CI/CD changesrevert: Reverting a previous commit
The scope should be the name of the affected module:
authwhatsappmediaapiuidbconfig
feat(auth): add JWT refresh token support
fix(whatsapp): resolve connection timeout issue
docs: update installation instructions
style(api): format code with prettier
refactor(media): simplify search logic
test(auth): add unit tests for login flow
chore(deps): update dependencies-
Update your branch with the latest main:
git checkout main git pull origin main git checkout your-feature-branch git rebase main
-
Run all checks:
npm run lint npm run format:check npm run test npm run build -
Update documentation if needed
-
Squash commits if you have many small commits:
git rebase -i main
-
Push your branch:
git push origin your-feature-branch
-
Create the pull request on GitHub
-
Fill out the PR template with:
- Clear description of changes
- Reference to related issues (e.g., "Closes #123")
- Screenshots/GIFs for UI changes
- Testing notes
-
Request review from maintainers
Use the same format as commit messages:
feat(scope): add new feature
fix(scope): resolve bug
- At least one maintainer must approve the PR
- All CI checks must pass
- All review comments must be addressed
- Code must follow our conventions
- Tests must be included for new functionality
- A maintainer will merge your PR
- Your branch will be deleted automatically
- You can delete your local branch:
git branch -d your-feature-branch
When creating an issue:
- Search first to avoid duplicates
- Use issue templates when available
- Be specific and provide context
- Include examples or code snippets
- Add labels to categorize the issue
bug- Something isn't workingenhancement- New feature or requestdocumentation- Documentation improvementsgood first issue- Good for newcomershelp wanted- Extra attention neededquestion- Further information requestedwontfix- Will not be worked onduplicate- Duplicate of another issueinvalid- Invalid issue
- Write tests for all new features
- Update tests when modifying existing features
- Aim for at least 80% code coverage
- Write both positive and negative test cases
tests/
├── unit/ # Unit tests for individual functions/classes
├── integration/ # Integration tests for API endpoints
└── e2e/ # End-to-end tests for full workflows
# Run all tests
npm run test
# Run specific test suite
npm run test:unit
npm run test:integration
npm run test:e2e
# Run with coverage
npm run test:coverage
# Run tests in watch mode
npm run test -- --watch- Use descriptive test names
- Follow the AAA pattern (Arrange, Act, Assert)
- Mock external dependencies
- Clean up after tests (reset database, clear mocks)
- Test edge cases and error conditions
import { describe, it, expect, beforeEach, afterEach } from "vitest";
describe("AuthService", () => {
let authService: AuthService;
beforeEach(() => {
authService = new AuthService();
});
afterEach(() => {
// Cleanup
});
describe("login", () => {
it("should return a token for valid credentials", async () => {
// Arrange
const email = "test@example.com";
const password = "password123";
// Act
const result = await authService.login(email, password);
// Assert
expect(result).toHaveProperty("token");
expect(result.token).toBeTruthy();
});
it("should throw error for invalid credentials", async () => {
// Arrange
const email = "test@example.com";
const password = "wrongpassword";
// Act & Assert
await expect(authService.login(email, password)).rejects.toThrow(
"Invalid credentials"
);
});
});
});- Document complex logic with comments
- Use JSDoc for public APIs
- Keep comments up to date with code changes
- Explain "why" not "what" in comments
Update README.md when:
- Adding new features
- Changing setup/installation process
- Modifying configuration options
- Adding new dependencies
Update API documentation when:
- Adding new endpoints
- Changing request/response formats
- Modifying authentication requirements
- Adding new query parameters
- Check the README for basic information
- Review existing issues
- Ask questions in discussions
- Reach out to maintainers if needed
By contributing to WAMR, you agree that your contributions will be licensed under the MIT License.
Thank you for contributing to WAMR! 🚀