๐Ÿ”
DevelopmentChapter 26 of 33ยท 5 min read

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:

  1. Describe what you expected vs. what happened
  2. Include your OpenClaw version (openclaw --version)
  3. Include relevant config (with secrets removed)
  4. 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/description for bug fixes
  • feat/description for new features
  • docs/description for documentation
  • refactor/description for 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:

PrefixWhen 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.