All posts
openhandsai-coding

OpenHands: A Practical Guide for Full-Stack Developers

A practical guide to OpenHands — setup, core concepts, common mistakes, and production tips for full-stack developers.

SR

Suhail Roushan

August 6, 2026

·
6 min read
·
0 views

OpenHands (formerly OpenDevin) turns an LLM into an autonomous coding agent that writes, edits, and runs code inside a Docker sandbox. Here's how to use it effectively on real full-stack projects without losing control of your codebase.

If you've used AI pair programmers like GitHub Copilot, OpenHands is a different beast: it's an agent that plans, executes shell commands, and iterates on failures until a task is done. For full-stack developers, that means it can scaffold a backend, write a React frontend, and wire them together — but only if you configure it correctly. This guide covers setup, core concepts, common pitfalls, and production tips I've learned from running OpenHands daily.

Why OpenHands Matters (and When to Skip It)

OpenHands matters because it shifts AI coding from "autocomplete" to "delegation." Instead of writing every line yourself, you describe a feature, and the agent does the grunt work: creating files, running tests, fixing errors, and committing changes. This is powerful for boilerplate-heavy work like REST APIs, database migrations, or repetitive CRUD screens.

But skip it when the task requires deep, undocumented business logic or when your codebase has unusual build steps. OpenHands works best in well-structured repos with clear tests. If your project lacks tests, the agent will confidently break things without noticing. In my experience, it's also not great at debugging subtle race conditions or complex state management — it lacks the context of a human who's been staring at the problem for hours.

Getting Started with OpenHands

The setup is straightforward: you need Docker and a GitHub account. Here's the minimal working configuration.

# Clone the repo
git clone https://github.com/All-Hands-AI/OpenHands.git
cd OpenHands

# Create a .env file with your LLM API key
echo "LLM_API_KEY=your_api_key_here" > .env
echo "LLM_MODEL=gpt-4o" >> .env

# Start the app
make build
make run

Then open http://localhost:3000, create a workspace, and link your GitHub repo. For a CLI-first workflow, you can also use the Python API:

from openhands.controller import AgentController
from openhands.llm import LLM

llm = LLM(model="gpt-4o", api_key="your_key")
controller = AgentController(llm=llm)
result = controller.run_task("Create a FastAPI backend with a /health endpoint")
print(result)

That's it. You're now delegating coding tasks to an autonomous agent.

Core OpenHands Concepts Every Developer Should Know

1. Tasks and Subtasks

OpenHands breaks your request into a task tree. You don't just say "build a todo app" — you say "build a todo app with a Node.js backend and a React frontend." The agent creates subtasks like "initialize npm project," "create Express server," and "set up React components." You can monitor progress in the UI.

2. The Action Space

The agent has a fixed set of actions: write, edit, run, browse. Here's a TypeScript example of how you'd programmatically invoke OpenHands to write a file:

import { OpenHandsClient } from 'openhands-sdk';

const client = new OpenHandsClient({
  apiKey: process.env.OPENHANDS_API_KEY,
  workspaceId: 'my-project',
});

const task = await client.createTask({
  prompt: 'Add a JWT auth middleware to the Express server',
  actions: ['write', 'run'], // restrict to write + run only
});

// Poll for completion
while (task.status !== 'completed') {
  await new Promise((r) => setTimeout(r, 2000));
  const updated = await client.getTask(task.id);
  console.log(`Progress: ${updated.progress}%`);
}

3. Sandboxing

Every OpenHands action runs inside a Docker container. This is critical: the agent can run npm install, execute tests, and even start servers — all isolated from your host machine. You define the sandbox environment in a config.toml file:

[sandbox]
image = "node:20-slim"
workdir = "/workspace"
volumes = ["./src:/workspace/src"]

4. Feedback Loops

OpenHands supports human-in-the-loop feedback. When it hits a failing test, it can pause and ask you for guidance. This is where you add guardrails — set MAX_ITERATIONS=10 in your env to prevent infinite loops.

Common OpenHands Mistakes and How to Fix Them

Mistake 1: Vague prompts. Saying "improve the login" yields garbage. Instead: "Refactor the login route in auth.ts to use bcrypt for password hashing, add rate limiting, and return proper 401 errors on failure." Specificity is everything.

Mistake 2: Ignoring the sandbox. The agent runs in an isolated container by default. If your project needs environment variables or a specific Node version, configure them in config.toml before starting. Otherwise, you'll get "module not found" errors that waste iterations.

Mistake 3: No tests before delegating. OpenHands relies on tests to validate its work. If you don't have a test suite, the agent will write code that "looks right" but breaks at runtime. Write at least one integration test before you hand off a task.

When Should You Use OpenHands?

Use OpenHands when you have a well-defined task with clear acceptance criteria and an existing test suite to validate the output. It excels at: generating CRUD endpoints, writing migration scripts, creating boilerplate components, and refactoring repetitive code across many files. It's also great for exploring unfamiliar libraries — ask it to "implement a Redis cache layer using best practices" and read the code it generates to learn.

Avoid it for: tasks requiring deep architectural judgment, debugging production incidents, or any work on a legacy codebase with surprising coupling. The agent will happily "fix" a file and break three others because it lacks the full system context.

OpenHands in Production

Tip 1: Use a dedicated branch. Never let OpenHands commit directly to main. Create a feature branch, let it work there, and review every diff before merging. Treat its output like a junior developer's PR — always review.

Tip 2: Set iteration and token limits. In your .env, set MAX_ITERATIONS=20 and MAX_TOKENS=20000. This prevents runaway costs and forces the agent to converge on a solution instead of wandering.

Tip 3: Cache the sandbox image. Building the Docker image every time is slow. Use docker commit after a successful session to save a stateful image, then reference it in config.toml. This cuts cold-start times from minutes to seconds.

The single most important thing: always run the test suite after OpenHands finishes. If tests pass, merge. If not, feed the failure output back into the agent with a prompt like "tests fail with X error, fix it." That feedback loop is what turns OpenHands from a toy into a reliable tool for full-stack development.

Related posts

Written by Suhail Roushan — Full-stack developer. More posts on AI, Next.js, and building products at suhailroushan.com/blog.

Get in touch