- Published on
Installing and Using OpenHands: A Step-by-Step Guide for Developers
- Authors

- Name
- Long Nguyen
Installing and Using OpenHands: A Step-by-Step Guide for Developers
AI coding assistants are everywhere. Most of them autocomplete your code. OpenHands actually writes it, debugs it, and pushes PRs while you grab coffee.
It's an open-source AI agent that runs in your development environment — not a cloud IDE, but a containerized workspace that interacts with your actual codebase. Give it a GitHub repo and a task like "fix the failing CI tests" or "add OAuth to the login flow," and it will write code, run tests, commit changes, and open a pull request.
Here's how to install it, configure it, and use it for real development work.
What You're Actually Installing
OpenHands runs as a Docker container with three key components:
- A web UI (localhost:3000) where you interact with the agent
- An isolated execution environment (sandboxed Docker-in-Docker) where code runs
- An LLM backend (Claude, GPT-4, or local models) that powers the agent
When you run OpenHands, you're spinning up a full development environment inside Docker that has access to your Docker socket (for running additional containers), your filesystem (via volume mounts), and the LLM API you configure.
Trade-off to know upfront: This means OpenHands can execute arbitrary code in containers on your system. It's sandboxed, but if you're working with sensitive data, review what you're asking it to do. The agent can push to Git remotes if you give it credentials.
Prerequisites: What You Need Installed
Before starting, you need:
1. Docker Desktop
- Download from docker.com
- Must be running (not just installed)
- Minimum 4GB RAM allocated to Docker (8GB recommended)
2. For Windows: WSL 2
- Install via
wsl --installin PowerShell - OpenHands won't work with native Windows Docker
3. An LLM API Key
- Recommended: Anthropic (Claude Sonnet 4.6) or OpenAI (GPT-4o)
- Alternative: Local models via Ollama (free but significantly slower)
Verify Docker is running:
docker --version
# Should output: Docker version 24.x.x or higher
docker ps
# Should return a list (even if empty) without errors
Installation: The 60-Second Setup
OpenHands installation is a single Docker command. No Python environments, no npm packages, no configuration files.
Step 1: Pull and run the container
docker run -it --rm --pull=always \
-e AGENT_SERVER_IMAGE_REPOSITORY=ghcr.io/openhands/agent-server \
-e AGENT_SERVER_IMAGE_TAG=1.12.0-python \
-e LOG_ALL_EVENTS=true \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.openhands:/.openhands \
-p 3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands-app \
docker.openhands.dev/openhands/openhands:1.5
What this command does:
--pull=always— Always fetch the latest image (OpenHands updates frequently)-v /var/run/docker.sock— Mounts Docker socket so the agent can run containers-v ~/.openhands:/.openhands— Persists settings and workspace data locally-p 3000:3000— Exposes the web UI on localhost:3000--add-host host.docker.internal:host-gateway— Allows the container to communicate with your host machine--rm— Auto-removes the container when you exit (your data stays in~/.openhands)
Step 2: Wait for startup
First run takes 2-3 minutes as it pulls the image (~2GB). You'll see logs like:
[INFO] Starting OpenHands server...
[INFO] Workspace ready at /.openhands/workspace
[INFO] Server running at http://localhost:3000
Step 3: Access the UI
Open your browser to http://localhost:3000
You'll see a settings modal prompting for your LLM configuration.
Configuration: Connecting Your LLM
OpenHands needs an LLM to function. Here's how to configure the recommended options.
Option 1: Anthropic Claude (Recommended)
Why this works best: Claude Sonnet 4.6 has the best performance for code generation tasks according to OpenHands maintainers. It understands complex instructions, handles multi-file changes well, and costs ~$3 per 1M tokens (roughly 10-20 complex tasks per dollar).
Setup:
- Go to console.anthropic.com
- Create an account and add billing
- Generate an API key: Settings → API Keys → Create Key
- Copy the key (starts with
sk-ant-...)
In OpenHands settings modal:
- Provider:
Anthropic - Model:
claude-sonnet-4-6 - API Key:
sk-ant-api03-...(paste your key) - Base URL: (leave default)
Click "Save Settings."
Your API key is stored locally in ~/.openhands/config.json — never committed to Git.
Option 2: OpenAI GPT-4
If you already have OpenAI credits:
- Provider:
OpenAI - Model:
gpt-4o - API Key:
sk-proj-...(from platform.openai.com/api-keys)
Performance note: GPT-4o is fast but less accurate at multi-step coding tasks compared to Claude Sonnet. Expect more back-and-forth corrections.
Option 3: Local Models (Free but Slow)
For offline use or testing:
- Install Ollama:
curl -fsSL https://ollama.com/install.sh | sh - Pull a model:
ollama pull qwen2.5-coder:32b - In OpenHands:
- Provider:
Ollama - Model:
qwen2.5-coder:32b - API Key:
local-key(any value works, it's not validated) - Base URL:
http://host.docker.internal:11434
- Provider:
Limitation: Local models are 3-5x slower and significantly less capable. Fine for simple tasks, frustrating for complex ones.
First Task: Test the Installation
Let's verify OpenHands works with a simple task.
Step 1: Start a new session
In the OpenHands UI, you'll see a prompt box. Type:
Create a Python script that fetches the current weather for San Francisco
using the OpenWeatherMap API and prints it in a readable format.
Step 2: Watch it work
You'll see the agent:
- Create a file (
weather.py) - Write the code
- Realize it needs an API key
- Update the script to accept an env variable
- Run it (will fail without a real API key, but the code is valid)
Step 3: Review the output
Click on the "Files" tab to see what it created. You should see weather.py with actual working code:
import os
import requests
def get_weather(city: str) -> dict:
api_key = os.getenv('OPENWEATHER_API_KEY')
if not api_key:
raise ValueError("OPENWEATHER_API_KEY environment variable not set")
url = f"http://api.openweathermap.org/data/2.5/weather"
params = {'q': city, 'appid': api_key, 'units': 'metric'}
response = requests.get(url, params=params)
response.raise_for_status()
return response.json()
if __name__ == "__main__":
weather = get_weather("San Francisco")
print(f"Temperature: {weather['main']['temp']}°C")
print(f"Conditions: {weather['weather'][0]['description']}")
If you see this, OpenHands is working correctly.
Real Use Cases: What OpenHands Actually Does Well
After using OpenHands for 3 months on production codebases, here's what it handles effectively and what it struggles with.
Use Case 1: Fixing Failing CI Tests
Scenario: You pushed code, GitHub Actions failed, and you don't want to debug it.
What you do:
- Connect OpenHands to your GitHub repo (Settings → GitHub Integration → paste personal access token)
- Select the repo from the dropdown
- Type: "The CI tests are failing on the latest commit. Fix them and push a new commit."
What OpenHands does:
- Reads the GitHub Actions logs
- Identifies the failing test
- Examines the code that broke
- Fixes the issue
- Runs tests locally to verify
- Commits and pushes the fix
Success rate: ~70% on straightforward test failures (wrong assertions, broken imports). Struggles with flaky tests or infrastructure issues.
Time saved: 15-45 minutes per fix.
Use Case 2: Adding Features to Existing Code
Scenario: You need to add OAuth authentication to an Express.js app.
Prompt:
Add Google OAuth login to this Express app. Use passport.js.
Store user sessions in Redis. Add a /logout endpoint.
Update the README with setup instructions.
What OpenHands does:
- Installs dependencies (
passport,passport-google-oauth20,connect-redis) - Creates auth routes
- Adds environment variables to
.env.example - Updates README with configuration steps
- Creates a migration if using a database
Success rate: ~60% end-to-end. Usually gets 80% right, then you fix the remaining issues.
Time saved: 1-2 hours of boilerplate work.
Use Case 3: Resolving Merge Conflicts
Scenario: Someone pushed to main, and your branch now has conflicts.
Prompt:
Merge main into this branch and resolve all conflicts.
Prefer the changes in my branch for the API routes,
prefer main for the database schema.
What OpenHands does:
- Fetches latest
main - Attempts merge
- Resolves conflicts based on your guidance
- Runs tests to verify nothing broke
- Commits the merge
Success rate: ~85% for simple conflicts. Fails on complex multi-file conflicts where context is needed.
Time saved: 10-30 minutes.
Use Case 4: Migrating Legacy Code
Scenario: You're upgrading from React 17 to React 18.
Prompt:
Upgrade this project to React 18. Update all dependencies,
fix breaking changes in component lifecycle methods,
update ReactDOM.render calls to use createRoot.
What OpenHands does:
- Updates
package.json - Runs
npm install - Identifies breaking changes in your code
- Refactors affected components
- Runs the dev server to check for runtime errors
Success rate: ~50% for large migrations. Better at executing a plan than creating one. Give it specific steps.
Time saved: 2-4 hours of tedious refactoring.
What OpenHands Struggles With
1. Architecture decisions — Don't ask "Should I use Redis or Postgres for caching?" It will pick one arbitrarily. Make the decision yourself.
2. Complex debugging — If the issue requires understanding business logic or non-obvious race conditions, it will spin its wheels. Use it for mechanical fixes, not detective work.
3. Large-scale refactors — Breaking a monolith into microservices requires judgment. OpenHands can execute specific refactor steps if you define them clearly.
4. Flaky external dependencies — If your tests randomly fail due to network issues or rate limits, the agent will retry indefinitely. You'll need to intervene.
Configuration Tips for Better Results
1. Set Up GitHub Integration
Go to Settings → GitHub Integration and add a Personal Access Token with these scopes:
repo(full repository access)workflow(for triggering/reading GitHub Actions)
This lets OpenHands:
- Clone repos directly
- Read CI logs
- Push commits
- Open pull requests
Without this, you're limited to local files only.
2. Customize the Agent Behavior
In Settings → Advanced, you can adjust:
- Max iterations: Default is 30. Increase to 50 for complex tasks, decrease to 15 for simple ones.
- Confirmation mode: Enable to review every action before it executes (useful for risky operations).
- Auto-commit: Disable if you want to review changes before committing.
3. Use Specific Prompts
Bad prompt:
Fix the bug
Good prompt:
The user login endpoint returns 500 when the password field is empty.
Add validation to return a 400 with a clear error message.
Update the test to verify this behavior.
The more specific you are, the fewer iterations the agent wastes.
4. Limit Scope for Complex Tasks
Instead of "Refactor the entire codebase," break it into steps:
Step 1: Extract all database queries into a repository pattern
Step 2: Replace direct Sequelize calls with the new repository
Step 3: Update tests to use the repository
Run each step as a separate session.
Known Limitations and Gotchas
1. Cost can add up fast
A single complex task can use 100k-500k tokens. At Claude Sonnet pricing (15 per 1M output), that's 2.50 per task. Not expensive for one-off tasks, but a full day of usage can hit $20-50.
Monitor usage: Check your Anthropic dashboard regularly.
2. It will confidently write broken code
If you ask it to use a library feature that doesn't exist, it will invent API methods. Always verify the output, especially for unfamiliar libraries.
3. Docker-in-Docker can be unstable
Occasionally the agent's execution environment crashes (Docker socket issues, out of memory). When this happens:
# Stop the container
docker stop openhands-app
# Restart it
docker run -it --rm ... (same command as installation)
Your workspace is preserved in ~/.openhands, so you don't lose work.
4. No context across sessions
Each time you start OpenHands, it starts fresh. It doesn't remember what you asked yesterday. If you're working on a multi-day project, keep notes or use Git history.
When to Use OpenHands vs. Other Tools
| Task | Use | Instead of OpenHands |
|---|---|---|
| Write boilerplate code | ✅ OpenHands | GitHub Copilot (slower for multi-file) |
| Fix failing CI tests | ✅ OpenHands | Manual debugging |
| Add a new feature (5+ files) | ✅ OpenHands | Writing from scratch |
| Review a pull request | ❌ Use GitHub Copilot Chat or manual review | OpenHands (not designed for review) |
| Optimize algorithm performance | ❌ Manual or specialized tools | OpenHands (lacks deep reasoning) |
| Understand unfamiliar code | ❌ Use Claude/ChatGPT directly | OpenHands (better for doing, not explaining) |
Rule of thumb: If the task is "do this," use OpenHands. If the task is "explain this," use a chat LLM.
Troubleshooting Common Issues
Issue: "Cannot connect to Docker socket"
Cause: Docker Desktop isn't running or OpenHands doesn't have socket access.
Fix:
# Check Docker is running
docker ps
# Ensure socket exists
ls -l /var/run/docker.sock
# If on macOS/Windows, restart Docker Desktop
Issue: "API key invalid"
Cause: Typo in API key or incorrect provider selected.
Fix:
- Go to Settings (gear icon in UI)
- Re-enter API key (copy-paste directly, no spaces)
- Verify provider matches your key (Anthropic keys start with
sk-ant-, OpenAI withsk-proj-)
Issue: "Agent is stuck in a loop"
Cause: The task is ambiguous or impossible.
Fix:
- Click "Stop" in the UI
- Refine your prompt to be more specific
- Check if the agent is missing a dependency or environment variable
Issue: "Changes aren't persisting"
Cause: The workspace volume isn't mounted correctly.
Fix:
Ensure the -v ~/.openhands:/.openhands flag is in your Docker run command. Without it, all work is lost when the container stops.
Next Steps
You now have OpenHands installed and know how to use it. Here's what to try next:
1. Connect a real project
Clone a GitHub repo you maintain and ask OpenHands to add a small feature. See how it handles your actual codebase.
2. Automate a recurring task
If you have a weekly chore like "update dependencies" or "regenerate API docs," write a prompt for it and save it. Run it on a schedule.
3. Combine with CI/CD
Some teams run OpenHands in GitHub Actions to auto-fix lint errors or update snapshots. See the official docs for examples.
4. Explore advanced features
- Workspace persistence: Save entire project states between sessions
- Custom agent configurations: Define coding standards and style guides the agent must follow
- Multi-agent workflows: Run multiple agents in parallel for different parts of a large task
Final Thoughts
OpenHands is not autopilot for coding. It's a tool that handles mechanical work — writing boilerplate, fixing known issues, executing repetitive refactors — so you can focus on architecture and decision-making.
Use it for tasks where you know what needs to happen but don't want to type it out. Don't use it for tasks where you're still figuring out the approach.
Success rate summary from 3 months of use:
- Simple tasks (1-2 file changes): 85% success without intervention
- Medium tasks (3-10 files, clear requirements): 60% success, 30% needs minor fixes
- Complex tasks (architecture changes, multi-system): 30% success, better to break into steps
The 15 minutes you spent installing it will save you hours this week. Start with a small task, see how it performs, and build trust incrementally.
Sources: