Building from Source
Building OpenClaw from source gives you access to unreleased features, lets you test a patched version, and is required for contributing code changes. This guide walks through the full build and test process for all supported platforms.
Prerequisites
| Requirement | Minimum version | Check |
|---|---|---|
| Python | 3.10 | python --version |
| Git | 2.30 | git --version |
| pip | 22.0 | pip --version |
| make (optional) | Any | make --version |
OpenClaw supports Python 3.10, 3.11, and 3.12. Python 3.9 and earlier are not supported. We recommend using Python 3.12 for development as it has the best performance and most recent language features.
Clone and Install
# Clone the main repository
git clone https://github.com/openclaw-ai/openclaw.git
cd openclaw
# (Optional) checkout a specific branch or tag
git checkout v0.9.0 # specific release
git checkout dev/feature-x # development branch
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\Activate.ps1 # Windows
# Install all dependencies including development extras
pip install -e ".[dev,test,docs]"
# Verify
openclaw --version
python -c "import openclaw; print(openclaw.__file__)"Running Tests
OpenClaw has three test suites with different dependencies and runtime requirements:
# Unit tests (no external dependencies, always runnable)
pytest tests/unit/ -v
# Integration tests (require OPENAI_API_KEY or local Ollama)
pytest tests/integration/ -v --api-key ${OPENAI_API_KEY}
# Full test suite with coverage report
pytest tests/ --cov=openclaw --cov-report=html
# View coverage: open htmlcov/index.html
# Run only tests matching a pattern
pytest tests/ -k "tool_creation" # tests with "tool_creation" in name
# Run specific test file
pytest tests/unit/test_tool_registry.py -vBuilding Distribution Packages
# Build wheel and sdist
pip install build
python -m build
# Outputs to dist/:
# openclaw-X.Y.Z-py3-none-any.whl
# openclaw-X.Y.Z.tar.gz
# Test the built wheel
pip install dist/openclaw-*.whl --force-reinstall
openclaw --versionDistribution builds are performed automatically by the release CI pipeline when a version tag is pushed. As a contributor, you typically don't need to build distributions manually unless you're testing the package install process itself.
Building the Docker Image
# Build the official Docker image locally
docker build -t openclaw:dev .
# Build with a non-default Python version
docker build -t openclaw:dev --build-arg PYTHON_VERSION=3.12 .
# Run the locally built image
docker run --rm openclaw:dev openclaw --version
# Run with your config mounted
docker run --rm -v $(pwd)/config.yaml:/app/config.yaml -e OPENAI_API_KEY=${OPENAI_API_KEY} openclaw:dev openclaw run "Hello, world"Troubleshooting Build Issues
Import errors after install: Ensure you installed with -e (editable) mode: pip install -e ".". Without -e, code changes won't be reflected without reinstalling.
Tests fail on import: Run pip check to detect dependency conflicts. A fresh virtual environment almost always resolves mysterious import failures.
Rust compilation errors: Some optional dependencies (e.g., tokenizers) require a Rust toolchain. Install from rustup.rs if needed.
Development Workflow
A productive development workflow for OpenClaw involves keeping a terminal with test feedback and a code editor open simultaneously. The suggested workflow for implementing a new feature:
- Open the relevant existing test files to understand the testing patterns
- Write failing tests for the new feature first (test-driven development)
- Implement the feature until tests pass
- Run the full test suite to check for regressions:
pytest tests/unit/ -v - Add integration test if the feature involves external services
- Run linting and type checking:
make check - Update CHANGELOG.md with your changes under "Unreleased"
# Run tests in watch mode during development (requires pytest-watch)
pip install pytest-watch
ptw tests/unit/ -- -v --tb=shortDevelopment Environment Variables
Several environment variables affect development-mode behavior:
| Variable | Purpose | Example |
|---|---|---|
OPENCLAW_DEV | Enable development mode (hot reload, verbose errors) | 1 |
OPENCLAW_LOG_LEVEL | Override log level for all loggers | DEBUG |
OPENCLAW_DISABLE_CACHE | Bypass response cache for reproducible testing | 1 |
OPENAI_API_KEY | Required for integration tests and LLM-hitting dev | sk-... |
OPENCLAW_MOCK_LLM | Replace LLM calls with echo mock (for fast unit tests) | 1 |
The OPENCLAW_MOCK_LLM=1 environment variable is particularly useful during development — it replaces all LLM calls with a simple echo mock that returns the last user message as the response. This lets you test tool invocation logic, pipeline structure, and output formatting without making API calls or consuming tokens.
CI Pipeline
OpenClaw uses GitHub Actions for CI. Understanding the CI pipeline helps you predict whether your PR will pass before pushing. The CI runs four jobs in parallel: test-unit (runs on every commit, no API keys), lint (black, ruff, mypy), test-integration (runs on main and release branches only), and build-docker (builds the Docker image to verify the Dockerfile). All four jobs must pass for a PR to be mergeable.
Platform-Specific Notes
Windows: OpenClaw is fully supported on Windows 10 and 11. Use PowerShell or Windows Terminal for the best experience. The execute_code tool defaults to PowerShell for command execution on Windows — to use bash-style commands, install the Windows Subsystem for Linux (WSL2) and configure the tool's shell to wsl bash. Long file paths (>260 chars) require enabling the "Long Path" feature in Windows registry or Group Policy.
macOS: Apple Silicon (M1/M2/M3) is fully supported from Python 3.10+. If you use Homebrew, install Python with brew install python rather than using the system Python. Some C-extension dependencies may require Xcode Command Line Tools; install them with xcode-select --install.
Linux: Ubuntu 22.04+ and Debian 12+ are the primary development targets. On systems using SELinux (RHEL, Fedora, CentOS), you may need to allow the process to bind to its configured port: semanage port -a -t http_port_t -p tcp 8080. Docker-based deployment is recommended for any production Linux environment.