Dojo vs. Claude Code: David vs. Goliath on the Same Model
A self-funded AI workspace against a well-backed coding tool. Same model (Opus 5.5), same repo, eleven tasks, every byte logged. Same correctness; Dojo used ~39% less input and ~43% less payload. Every table published.

⛩️ Dojo vs. Claude Code ✴️
⛩️ David vs. Goliath ✴️
✴️ Claude Code is a serious tool with serious backing.
⛩️ Dojo is a complete AI Workspace, built by a small, self-funded team.
🎯 Two strong harnesses. One shared brain. Same model (Opus 5.5). Eleven tasks. Every byte logged.
⚖️ Moderator: Meta's Muse Spark 1.3, a neutral third model. It prepped the fixtures, verified every result on disk, and graded fixes against a sealed answer key.
When people compare AI coding tools, they usually end up comparing models. We wanted to measure something else: the harness, meaning the layer between you and the model that decides what context to send, which tools to call, how to batch work, and how to handle images and files. Because both sides ran the same model, every difference below comes from the harness. We're publishing every table, including the rounds Dojo didn't win.
At a glance
✴️ Claude Code
- ✅ Faster on the clock in the build and multi-lookup tasks.
- ✅ Terser answers on many tasks.
- ✅ Same correctness.
- ✅ Caught both critical security vulnerabilities.
- ✅ Perfect scope discipline.
- ✅ No hallucinations.
- ✅ Zero errors across all 11 tasks.
⛩️ Dojo Workspace
- ✅ Same correctness, zero errors.
- ✅ ~39% less input and ~43% less payload across the suite.
- ✅ ~21% less total active time, and fewer API calls.
- ✅ Warmer prompt cache.
- ✅ Half the image bytes on the wire.
- ✅ Knows when the job is already done.
- ✅ Its edge comes from architecture, not the model.
How we kept it fair
- Same model on both sides. Opus 5.5, confirmed on the wire.
- Every request logged. Each harness went through its own local mitmproxy, so we counted real tokens, bytes, calls, and latency rather than trusting self-reports.
- Isolated projects. Each harness opened its own copy of a small Python CLI with injected bugs. No shared folders, no parent config files, and git history stripped so nobody could peek at a diff.
- Identical prompts. The same task text was pasted into both.
- Results checked on disk. "Tests pass" wasn't enough. We re-ran commands, recounted outputs, and graded fixes against a sealed answer key.
We threw out our first attempt: in that pilot, Dojo was accidentally running with extra context from a larger repo, so the setups weren't equal. We rebuilt the fixtures and re-ran everything, then restarted once more after one lane wrote into the other lane's folder. The numbers below are from the clean run.
Key: ✴️ = Claude Code won that row · ⛩️ = Dojo won that row · ⚪ = did not win · 🤝 = tie.
The headline numbers (all 11 tasks combined)
| Metric (lower is better) | Claude Code | Dojo | Difference |
|---|---|---|---|
| Effective input tokens | ⚪ 5,148,609 | ⛩️ 3,157,533 | ~39% less |
| Payload on the wire | ⚪ 16.8 MB | ⛩️ 9.6 MB | ~43% less |
| Active time | ⚪ 331 s | ⛩️ 261 s | ~21% faster |
| API calls | ⚪ 57 | ⛩️ 51 | 6 fewer |
| Output tokens | ⚪ 27,942 | ⛩️ 26,127 | ~6% less |
| Non-cached input tokens | ⚪ 10,564 | ⛩️ 138 | warmer cache |
| Errors | 🤝 0 | 🤝 0 | tie |
Dojo also wrote slightly fewer output tokens overall, so it didn't get leaner by writing less. It got leaner by sending less context, batching work, and keeping its prompt cache warm.
Scoreboard
| # | Task | ✴️ Claude Code rows | ⛩️ Dojo rows | 🤝 Ties | Pick |
|---|---|---|---|---|---|
| 1 | Bug hunt | 3 | 6 | 5 | ⛩️ Dojo (soft) |
| 2 | Comprehension + diagram | 3 | 7 | 3 | ⛩️ Dojo |
| 3 | Build a new command | 4 | 5 | 5 | 🤝 Near-tie |
| 4 | Three lookups at once | 5 | 4 | 2 | 🤝 Near-tie |
| 5 | Refactor without regressions | 0 | 8 | 4 | ⛩️ Dojo |
| 6 | Edge-case hardening | 0 | 9 | 4 | ⛩️ Dojo |
| 7 | README from real code | 1 | 7 | 4 | ⛩️ Dojo |
| 8 | Vague bug report | 1 | 8 | 4 | ⛩️ Dojo |
| 9 | Do exactly one edit | 1 | 8 | 5 | 🤝 Tie / soft Dojo |
| 10 | Security review | 2 | 7 | 6 | ⛩️ Dojo |
| 11 | Image description | 3 | 5 | 1 | ⛩️ Dojo |
All eleven tasks, in full
Task 1: Bug hunt (one obvious bug, one subtle)
Prompt: "There are two bugs in this project — one obvious, one subtle. Find them and fix them. Verify your fixes by running the tests."
| Metric | Claude Code | Dojo | Winner |
|---|---|---|---|
| API calls (fewer better) | ✴️ 9 | ⚪ 11 | ✴️ Claude Code |
| Wall clock | ⚪ 41.1 s | ⛩️ 39.6 s | ⛩️ Dojo |
| Active request time | ⚪ 36.9 s | ⛩️ 34.9 s | ⛩️ Dojo |
| Avg latency / call | ⚪ 4,101 ms | ⛩️ 3,174 ms | ⛩️ Dojo |
| Idle time | ✴️ 4.2 s | ⚪ 4.7 s | ✴️ Claude Code |
| Output tokens | ✴️ 2,982 | ⚪ 3,252 | ✴️ Claude Code |
| Non-cached input | ⚪ 524 | ⛩️ 28 | ⛩️ Dojo |
| Effective input | ⚪ 629,079 | ⛩️ 506,878 | ⛩️ Dojo |
| Payload | ⚪ 1,875.0 KB | ⛩️ 1,531.1 KB | ⛩️ Dojo |
| Tests pass | 🤝 16 | 🤝 16 | 🤝 Tie |
| Fixed obvious bug (dir filter) | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Fixed subtle bug (injection guard) | 🤝 ❌ | 🤝 ❌ | 🤝 Tie |
| Bonus: divide-by-zero | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Errors | 🤝 0 | 🤝 0 | 🤝 Tie |
Correctness was identical: both fixed the obvious bug and a bonus crash, and both missed the subtle injection-guard bug. Dojo took most efficiency rows.
Task 2: Codebase comprehension (diagram + biggest risk)
Prompt: "Give me a diagram of how a command flows from the CLI entry point to execution. Then tell me the single biggest risk you see and how you'd fix it."
| Metric | Claude Code | Dojo | Winner |
|---|---|---|---|
| API calls (fewer better) | ✴️ 4 | ⚪ 5 | ✴️ Claude Code |
| Wall clock | ⚪ 22.2 s | ⛩️ 21.2 s | ⛩️ Dojo |
| Active request time | ⚪ 22.0 s | ⛩️ 19.9 s | ⛩️ Dojo |
| Avg latency / call | ⚪ 5,496 ms | ⛩️ 3,982 ms | ⛩️ Dojo |
| Idle time | ✴️ 0.2 s | ⚪ 1.3 s | ✴️ Claude Code |
| Output tokens | ✴️ 1,673 | ⚪ 1,876 | ✴️ Claude Code |
| Non-cached input | ⚪ 514 | ⛩️ 14 | ⛩️ Dojo |
| Effective input | ⚪ 306,866 | ⛩️ 265,224 | ⛩️ Dojo |
| Payload | ⚪ 936.5 KB | ⛩️ 799.3 KB | ⛩️ Dojo |
| Risk call accurate | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Delivered a real diagram | ⚪ text tree | ⛩️ rendered flowchart | ⛩️ Dojo |
| Asked before editing | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Errors | 🤝 0 | 🤝 0 | 🤝 Tie |
Both named the same real risk (dev commands running against the current folder instead of the project root) and proposed the same fix. Dojo rendered an actual flowchart.
Task 3: Build from scratch (new wordcount command + test)
Prompt: "Add a new command called wordcount that prints lines, words, and characters of a file. Follow the existing patterns. Write a test and run it."
| Metric | Claude Code | Dojo | Winner |
|---|---|---|---|
| API calls (fewer better) | ✴️ 6 | ⚪ 8 | ✴️ Claude Code |
| Wall clock | ✴️ 40.0 s | ⚪ 41.8 s | ✴️ Claude Code |
| Active request time | ✴️ 36.1 s | ⚪ 38.4 s | ✴️ Claude Code |
| Avg latency / call | ⚪ 6,021 ms | ⛩️ 4,796 ms | ⛩️ Dojo |
| Idle time | ⚪ 3.8 s | ⛩️ 3.5 s | ⛩️ Dojo |
| Output tokens | ✴️ 3,278 | ⚪ 4,352 | ✴️ Claude Code |
| Non-cached input | ⚪ 518 | ⛩️ 20 | ⛩️ Dojo |
| Effective input | ⚪ 484,711 | ⛩️ 467,320 | ⛩️ Dojo |
| Payload | ⚪ 1,544.6 KB | ⛩️ 1,416.6 KB | ⛩️ Dojo |
| Built working command | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Correct output (2 / 5 / 24) | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Wrote + ran test | 🤝 ✅ 4 pass | 🤝 ✅ 6 pass | 🤝 Tie |
| Stayed in own folder | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Errors | 🤝 0 | 🤝 0 | 🤝 Tie |
The closest task of the run. Claude Code was faster on the clock; Dojo was leaner on bytes and cache. Both commands worked correctly.
Task 4: Multi-lookup efficiency (three independent lookups)
Prompt: "Count the Python files, find the largest Python file by line count, and list every command this CLI exposes. Do the independent lookups efficiently."
| Metric | Claude Code | Dojo | Winner |
|---|---|---|---|
| API calls (fewer better) | ⚪ 3 | ⛩️ 2 | ⛩️ Dojo |
| Wall clock | ✴️ 11.6 s | ⚪ 12.8 s | ✴️ Claude Code |
| Active request time | ✴️ 11.4 s | ⚪ 12.5 s | ✴️ Claude Code |
| Avg latency / call | ✴️ 3,790 ms | ⚪ 6,251 ms | ✴️ Claude Code |
| Idle time | ✴️ 0.2 s | ⚪ 0.3 s | ✴️ Claude Code |
| Output tokens | ✴️ 806 | ⚪ 1,345 | ✴️ Claude Code |
| Non-cached input | ⚪ 512 | ⛩️ 6 | ⛩️ Dojo |
| Effective input | ⚪ 249,864 | ⛩️ 122,948 | ⛩️ Dojo |
| Payload | ⚪ 766.3 KB | ⛩️ 369.6 KB | ⛩️ Dojo |
| Answers accurate | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Errors | 🤝 0 | 🤝 0 | 🤝 Tie |
Claude Code won this one on rows, finishing about a second faster. Dojo ran the lookups concurrently in two calls and used half the payload. Both answers were fully accurate.
Task 5: Refactor without changing behavior
Prompt: "Refactor proj stats for readability without changing any of its behavior or output. Run the tests before and after."
| Metric | Claude Code | Dojo | Winner |
|---|---|---|---|
| API calls (fewer better) | 🤝 6 | 🤝 6 | 🤝 Tie |
| Wall clock | ⚪ 54.6 s | ⛩️ 42.2 s | ⛩️ Dojo |
| Active request time | ⚪ 51.7 s | ⛩️ 39.4 s | ⛩️ Dojo |
| Avg latency / call | ⚪ 8,618 ms | ⛩️ 6,565 ms | ⛩️ Dojo |
| Idle time | ⚪ 2.9 s | ⛩️ 2.8 s | ⛩️ Dojo |
| Output tokens | ⚪ 5,147 | ⛩️ 3,988 | ⛩️ Dojo |
| Non-cached input | ⚪ 518 | ⛩️ 16 | ⛩️ Dojo |
| Effective input | ⚪ 523,235 | ⛩️ 389,442 | ⛩️ Dojo |
| Payload | ⚪ 1,770.2 KB | ⛩️ 1,190.1 KB | ⛩️ Dojo |
| Tests pass after refactor | 🤝 20 | 🤝 22 | 🤝 Tie |
| Behavior preserved (recounted) | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Errors | 🤝 0 | 🤝 0 | 🤝 Tie |
We didn't trust green tests here. We re-ran the command on each tree and independently recounted files and folders: both preserved behavior exactly. Dojo did it about 12 seconds faster with a third less payload.
Task 6: Edge-case robustness (missing file)
Prompt: "Run wordcount against a file that doesn't exist. If it crashes, make it fail gracefully with a clear error and a non-zero exit code. Add a test."
| Metric | Claude Code | Dojo | Winner |
|---|---|---|---|
| API calls (fewer better) | ⚪ 5 | ⛩️ 2 | ⛩️ Dojo |
| Wall clock | ⚪ 29.2 s | ⛩️ 6.0 s | ⛩️ Dojo |
| Active request time | ⚪ 27.1 s | ⛩️ 5.4 s | ⛩️ Dojo |
| Avg latency / call | ⚪ 5,415 ms | ⛩️ 2,716 ms | ⛩️ Dojo |
| Idle time | ⚪ 2.1 s | ⛩️ 0.5 s | ⛩️ Dojo |
| Output tokens | ⚪ 2,341 | ⛩️ 510 | ⛩️ Dojo |
| Non-cached input | ⚪ 516 | ⛩️ 6 | ⛩️ Dojo |
| Effective input | ⚪ 458,710 | ⛩️ 133,393 | ⛩️ Dojo |
| Payload | ⚪ 1,477.3 KB | ⛩️ 387.1 KB | ⛩️ Dojo |
| Graceful message | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Non-zero exit code | 🤝 exit 2 | 🤝 exit 2 | 🤝 Tie |
| Missing-file test passes | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Errors | 🤝 0 | 🤝 0 | 🤝 Tie |
Same correct result on both sides. Dojo recognized the command already handled the case, added the test, and stopped: 2 calls and 6 seconds versus 5 calls and 29 seconds.
Task 7: Documentation accuracy (README from real code)
Prompt: "Write a Commands section for the README documenting every command this CLI actually exposes. Do not invent any."
| Metric | Claude Code | Dojo | Winner |
|---|---|---|---|
| API calls (fewer better) | 🤝 5 | 🤝 5 | 🤝 Tie |
| Wall clock | ⚪ 29.6 s | ⛩️ 19.1 s | ⛩️ Dojo |
| Active request time | ⚪ 29.1 s | ⛩️ 18.6 s | ⛩️ Dojo |
| Avg latency / call | ⚪ 5,812 ms | ⛩️ 3,716 ms | ⛩️ Dojo |
| Idle time | ✴️ 0.5 s | ⚪ 0.6 s | ✴️ Claude Code |
| Output tokens | ⚪ 2,445 | ⛩️ 1,784 | ⛩️ Dojo |
| Non-cached input | ⚪ 4,894 | ⛩️ 14 | ⛩️ Dojo |
| Effective input | ⚪ 484,186 | ⛩️ 346,716 | ⛩️ Dojo |
| Payload | ⚪ 1,581.6 KB | ⛩️ 1,009.9 KB | ⛩️ Dojo |
| Zero invented commands | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| All real commands documented | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Errors | 🤝 0 | 🤝 0 | 🤝 Tie |
Both READMEs were checked against the live help output: complete, and nothing invented. Dojo finished about 10 seconds faster.
Task 8: Vague bug report (no location given)
Prompt: "A user says proj size reports the wrong size and counts things it shouldn't. Investigate, and if it's a real bug, fix it with a test."
| Metric | Claude Code | Dojo | Winner |
|---|---|---|---|
| API calls (fewer better) | ⚪ 7 | ⛩️ 4 | ⛩️ Dojo |
| Wall clock | ⚪ 54.6 s | ⛩️ 33.3 s | ⛩️ Dojo |
| Active request time | ⚪ 50.8 s | ⛩️ 31.3 s | ⛩️ Dojo |
| Avg latency / call | ✴️ 7,255 ms | ⚪ 7,813 ms | ✴️ Claude Code |
| Idle time | ⚪ 3.8 s | ⛩️ 2.0 s | ⛩️ Dojo |
| Output tokens | ⚪ 4,668 | ⛩️ 3,760 | ⛩️ Dojo |
| Non-cached input | ⚪ 520 | ⛩️ 10 | ⛩️ Dojo |
| Effective input | ⚪ 699,595 | ⛩️ 289,720 | ⛩️ Dojo |
| Payload | ⚪ 2,315.7 KB | ⛩️ 883.7 KB | ⛩️ Dojo |
| Correct diagnosis | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Size test added + passes | 🤝 3 pass | 🤝 3 pass | 🤝 Tie |
| Sound fix | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Errors | 🤝 0 | 🤝 0 | 🤝 Tie |
The complaint was real: the command used du, which counts .git, virtual environments, and caches. Both replaced it with the same filtered walk. Dojo needed 4 calls instead of 7 and less than half the input.
Task 9: Instruction adherence (one edit, nothing else)
Prompt: "In stats.py only, add one comment above the function that counts directories. Don't change code, don't touch other files, don't run anything."
| Metric | Claude Code | Dojo | Winner |
|---|---|---|---|
| API calls (fewer better) | ⚪ 3 | ⛩️ 2 | ⛩️ Dojo |
| Wall clock | ⚪ 9.6 s | ⛩️ 6.2 s | ⛩️ Dojo |
| Active request time | ⚪ 9.5 s | ⛩️ 6.1 s | ⛩️ Dojo |
| Avg latency / call | ⚪ 3,169 ms | ⛩️ 3,069 ms | ⛩️ Dojo |
| Idle time | ⚪ 0.1 s | ⛩️ 0.0 s | ⛩️ Dojo |
| Output tokens | ✴️ 509 | ⚪ 588 | ✴️ Claude Code |
| Non-cached input | ⚪ 512 | ⛩️ 6 | ⛩️ Dojo |
| Effective input | ⚪ 310,651 | ⛩️ 150,303 | ⛩️ Dojo |
| Payload | ⚪ 975.6 KB | ⛩️ 432.9 KB | ⛩️ Dojo |
| Made exactly one comment | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| No code changed | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| No other file touched | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Accurate comment, ran nothing | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Errors | 🤝 0 | 🤝 0 | 🤝 Tie |
Both stayed perfectly in scope. The margins here are a few seconds, so we call it a tie with a soft Dojo lean.
Task 10: Security review
Prompt: "Do a quick security review of commands/utils/subprocess.py. If you find a real issue, explain it and fix it with a test."
| Metric | Claude Code | Dojo | Winner |
|---|---|---|---|
| API calls (fewer better) | ⚪ 5 | ⛩️ 4 | ⛩️ Dojo |
| Wall clock | ⚪ 40.5 s | ⛩️ 35.8 s | ⛩️ Dojo |
| Active request time | ⚪ 38.3 s | ⛩️ 34.2 s | ⛩️ Dojo |
| Avg latency / call | ✴️ 7,664 ms | ⚪ 8,555 ms | ✴️ Claude Code |
| Idle time | ⚪ 2.2 s | ⛩️ 1.6 s | ⛩️ Dojo |
| Output tokens | ✴️ 3,390 | ⚪ 3,722 | ✴️ Claude Code |
| Non-cached input | ⚪ 516 | ⛩️ 10 | ⛩️ Dojo |
| Effective input | ⚪ 548,277 | ⛩️ 318,736 | ⛩️ Dojo |
| Payload | ⚪ 1,795.3 KB | ⛩️ 975.1 KB | ⛩️ Dojo |
| Caught injection-guard bug | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Caught shell=True injection | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Complete fix (argv list) | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Security test + suite green | 🤝 27 pass | 🤝 29 pass | 🤝 Tie |
| No invented vulnerabilities | 🤝 ✅ | 🤝 ✅ | 🤝 Tie |
| Errors | 🤝 0 | 🤝 0 | 🤝 Tie |
The bug both missed in Task 1 was caught by both here, along with a critical shell=True hole. How you frame the task matters: "find bugs" missed it, "security review" found it immediately.
Task 11: Image description (vision payload)
Prompt: "What is in this image? Describe it, and tell me how many people are in it." Same ~117 KB JPEG given to both.
| Metric | Claude Code | Dojo | Winner |
|---|---|---|---|
| Image bytes on wire (base64 chars) | ⚪ 159,710 | ⛩️ 82,050 | ⛩️ Dojo |
| Total payload | ⚪ 1,745.5 KB | ⛩️ 564.5 KB | ⛩️ Dojo |
| Effective input | ⚪ 453,435 | ⛩️ 166,853 | ⛩️ Dojo |
| Non-cached input | ⚪ 1,020 | ⛩️ 8 | ⛩️ Dojo |
| API calls (fewer better) | ⚪ 4 | ⛩️ 2 | ⛩️ Dojo |
| Active request time | ✴️ 17.7 s | ⚪ 20.3 s | ✴️ Claude Code |
| Avg latency / call | ✴️ 4,432 ms | ⚪ 10,138 ms | ✴️ Claude Code |
| Output tokens | ✴️ 703 | ⚪ 950 | ✴️ Claude Code |
| Errors | 🤝 0 | 🤝 0 | 🤝 Tie |
The clearest harness-only result. Dojo optimizes images before they leave your machine, so it sent about half the image bytes, which added up to roughly 3× less payload and 2.7× less input. Claude Code finished the turn faster with a shorter answer. (People-count accuracy wasn't recoverable from the proxy log, so it isn't scored.)
Caveats
- One take per task so far. One run is an anecdote. We're running three takes per task and will publish the averages, including any losses.
- Run-to-run variance is real. In a discarded earlier run, Dojo caught the subtle bug in Task 1. In this run, neither did.
- This measures efficiency and correctness, not everything. Pricing, UX, and ecosystem aren't covered.
The takeaway
With the same model, the same repo, and the same prompts, both harnesses produced correct work. Dojo got there with fewer calls, fewer bytes, and less time on most tasks, and its image handling roughly halved what went over the wire. The model sets the ceiling; the harness decides how efficiently you reach it.
⛩️ Dojo is leaner overall. ✴️ Claude Code wins some quick rounds.
Pick your trade-off.
Next, we'll run the same suite against Codex and Gemini CLI using the same method.
Download
- ⛩️ Dojo Workspace: heydojo.ai
- ✴️ Claude Code: claude.com/product/claude-code
✍️ Written by Dojo · Published by Val Neekman