Chapter 26: Contributing to OpenClaw
OpenClaw is an open-source project and welcomes contributions from everyone โ whether you want to fix a bug, add a new channel, improve documentation, or build a new skill. This chapter explains how the project works, how to set up a development environment, and how to submit your changes.
Project Structure
openclaw/
โโโ packages/
โ โโโ core/ # Gateway core, message routing, session management
โ โโโ channels/ # Channel adapters (telegram, slack, whatsapp, etc.)
โ โโโ skills/ # Built-in skills
โ โโโ agents/ # Agent provider adapters (anthropic, openai, etc.)
โ โโโ cli/ # The `openclaw` CLI
โ โโโ api/ # REST API server
โ โโโ web/ # Dashboard UI
โโโ apps/
โ โโโ ios/ # iOS Node (Swift)
โ โโโ android/ # Android Node (Kotlin)
โโโ docs/ # Documentation source
โโโ scripts/ # Build and release scripts
OpenClaw uses a monorepo managed with Turborepo. Each package is independently versioned and published to npm.
Setting Up the Development Environment
Prerequisites
- Node.js 20 or later
- Git
- pnpm (
npm install -g pnpm)
Clone and Install
git clone https://github.com/openclaw/openclaw.git
cd openclaw
pnpm install
Build All Packages
pnpm build
Run Tests
pnpm test
Start the Gateway in Development Mode
pnpm --filter @openclaw/cli dev
The gateway starts with hot reload enabled โ code changes restart the relevant package automatically.
Finding Something to Work On
Good First Issues
Issues labeled good-first-issue on GitHub are specifically chosen for new contributors. They are small, well-defined, and have enough context to get started without deep knowledge of the codebase.
https://github.com/openclaw/openclaw/issues?q=label%3Agood-first-issue
Bug Reports
If you found a bug, check if it's already reported before opening a new issue. When filing a bug:
- Describe what you expected vs. what happened
- Include your OpenClaw version (
openclaw --version) - Include relevant config (with secrets removed)
- Include error logs if available
Feature Requests
Open a GitHub Discussion before building a large feature to get early feedback on the design. This saves you from building something that won't be merged due to architectural concerns.
Making Changes
1. Fork and Branch
# Fork on GitHub, then:
git clone https://github.com/your-username/openclaw.git
cd openclaw
git checkout -b fix/telegram-markdown-parsing
Branch naming conventions:
fix/descriptionfor bug fixesfeat/descriptionfor new featuresdocs/descriptionfor documentationrefactor/descriptionfor refactors
2. Make Your Changes
Edit the relevant package in packages/. The code is TypeScript throughout.
3. Write Tests
Every bug fix should have a test that would have caught the bug. New features should have integration tests that verify the happy path and key error cases.
Tests live in __tests__/ directories within each package.
4. Run the Full Test Suite
pnpm test
pnpm typecheck
pnpm lint
All three must pass before submitting.
5. Commit Your Changes
git add .
git commit -m "fix: handle markdown bold syntax in Telegram channel adapter"
OpenClaw uses Conventional Commits:
| Prefix | When to Use |
|---|---|
fix: | Bug fix |
feat: | New feature |
docs: | Documentation only |
refactor: | Code change that is neither a fix nor a feature |
test: | Adding or fixing tests |
chore: | Build process or tooling changes |
6. Push and Open a PR
git push origin fix/telegram-markdown-parsing
Then open a Pull Request on GitHub. The PR template asks you to:
- Describe the change and why it was needed
- Link the related issue
- Describe how you tested it
- Note any breaking changes
Adding a New Channel
To add support for a new messaging platform, create a new channel adapter:
packages/channels/src/adapters/my-new-channel/
โโโ index.ts # Main adapter class
โโโ types.ts # TypeScript types for the platform's API
โโโ auth.ts # Authentication / connection logic
โโโ receive.ts # Convert incoming messages to OpenClaw format
โโโ send.ts # Convert OpenClaw messages to platform format
โโโ __tests__/
โโโ adapter.test.ts
Implement the ChannelAdapter interface from @openclaw/core:
import { ChannelAdapter, IncomingMessage, OutgoingMessage } from '@openclaw/core';
export class MyNewChannelAdapter implements ChannelAdapter {
async connect(config: MyChannelConfig): Promise<void> { ... }
async disconnect(): Promise<void> { ... }
async send(message: OutgoingMessage): Promise<void> { ... }
onMessage(handler: (msg: IncomingMessage) => void): void { ... }
}
Code Review Process
All PRs are reviewed by a maintainer within 5 business days. The review focuses on:
- Correctness: Does the code do what it says?
- Tests: Is the behavior tested?
- Security: Does the change introduce any vulnerabilities?
- Compatibility: Does it work with existing configs without breaking changes?
Be responsive to review comments. PRs that go 30 days without a response from the author are closed.
Documentation
Documentation source lives in docs/. It uses MDX (Markdown + JSX).
# Run docs site locally
pnpm --filter docs dev
Good documentation contributions are highly valued and often merged faster than code changes.
Next: Chapter 27 โ Self-Hosting with Docker โ How to deploy OpenClaw as a production-grade Docker container with proper networking, persistence, and monitoring.