Which AI Coding Agent Works Best with a Local LLM? Four Tools Tested on a DGX Spark
This blog post is an informal comparison of four AI coding agents running against a locally hosted LLM. If you followed my earlier posts on running a local model on a DGX Spark (here and here), the next question is the one my customers ask: which coding agent should I point at it? So on September 9, 2026 I ran the same task through all four and scored the output with an automated test.
TL;DR, OpenCode won. qwen-code tied it on quality but took longer. Claude Code got 11 of 12 checks but ran for over an hour. Codex produced nothing on the first run and a broken page on the second. Details below.
What I tested
The model was Qwen3.8-Flash-Next (NVFP4) served by vLLM on a single DGX Spark, the same setup from my last post. The four agents:
| Agent | Version | Made by |
|---|---|---|
| OpenCode | 1.18.30 | open source |
| qwen-code | 0.23.2 | Alibaba (open source) |
| Claude Code | 2.1.267 | Anthropic |
| Codex CLI | 0.147.0 | OpenAI |
All four support pointing at an OpenAI-compatible endpoint, so they all talked to the same server and the same model id. Nothing left the box.
The task was deliberately small: write a single-file stopwatch web page (index.html) with start, stop, reset, and lap buttons, a mm:ss.cc display, Space to toggle, laps saved to localStorage, no external resources. The prompt listed the exact element ids and ended with "Do not ask questions; make reasonable decisions and proceed." Each agent got 20 minutes, unattended, with approvals disabled.
I scored the result with a Playwright script that loads the page in a headless browser and runs 12 checks: the file exists, no external resources, all ids present, starts at 00:00.00, runs, stops, resumes, lap adds an <li>, laps survive a reload, reset clears everything, Space toggles, and nothing throws in the console. Pass or fail, no partial credit, no opinions from me.
The Numbers
| Agent | Score | Wall time | Requests to vLLM | Prompt tokens sent |
|---|---|---|---|---|
| OpenCode | 12/12 | 11.7 min | 34 | 1.9M |
| qwen-code | 12/12 | 16.4 min | 59 | 2.9M |
| Claude Code | 11/12 | 60+ min (I killed it) | n/a | n/a |
| Codex, run 1 | 0/12 | 9.7 min | 17 | 0.8M |
| Codex, run 2 | 6/12 | 20 min (hit the cap) | 47 | 3.3M |
The "prompt tokens" column is from vLLM's own counters, not the agent's estimate. It is the total the agent sent to the model over the whole run, and it is the number that matters on a local box because it is where your wall time goes. Codex sent 3.3 million tokens to produce a broken page. OpenCode sent 1.9 million to produce a working one.
What each one did
OpenCode wrote the file, ran a quick check, and stopped. 34 requests. No drama. It also has the best config story: one JSON file at ~/.config/opencode/opencode.json defines the provider and model, and opencode run -m vllm/qwen3.8-flash-next "..." uses it.
qwen-code got the same 12/12 but took 59 requests to do it, because it kept reading the file back and checking its own work. That turned out to be a feature: the model garbled a variable name mid-file, and qwen-code caught it and fixed it. More on that below.
Claude Code produced a nearly correct page but then looped on verification for an hour. The one failing check was localStorage persistence, and the cause was a typo the model wrote: stORAGE_KEY instead of STORAGE_KEY. It never found it. I killed the run at 60 minutes.
Codex, run 1 was the strange one. The model wrote "I'll create index.html with all CSS and JavaScript inline" and then ended its turn. No tool call, no file. 17 requests of that. I logged it as 0/12 and moved on.
Codex, run 2 was the identical test. This time it behaved like an agent: 47 requests, a real bash command that wrote an 8,315 byte index.html, a node syntax check, some sed fixes, another check. Then it hit the 20 minute cap mid-loop. The page passed every static check and failed every behavioral one, because line 323 of the JavaScript reads:
element.addEventList...;
That is not a typo, it is the model giving up halfway through addEventListener and typing three dots. The browser sees Unexpected token '...' and the script never runs. Codex's repair attempts made it worse: it "fixed" DOM calls into createLIElement and querySelectorALL, and called fs.readfiletostring, none of which exist.
The identifier problem
This is the thing to know if you run Flash-Next (or in my opinion any of the current local models) behind a coding agent: it mangles identifiers. camelCase DOM APIs come out with the wrong letters capitalized, constants get a lowercase run in the middle, and occasionally the model just stops typing a name. Three of the four agents hit it:
- Claude Code:
stORAGE_KEY - Codex:
addEventList...,createLIElement,querySelectorALL - qwen-code: also mangled one, but read the file back, noticed, and fixed it
The agents that finish are the ones that verify their own output by actually running it, not the ones with the most polished prompts. qwen-code's habit of re-reading files looked wasteful in the request count and turned out to be exactly what the model needed.
Should you use these with a local model?
Yes, with the right one. Here is what I recommend as of today:
- OpenCode for unattended and scripted work against a local model. Fastest, cheapest in tokens, one config file.
- qwen-code if you want a second opinion. Same score, slower, and its self-checking is worth the extra requests on a model that mangles names.
- Claude Code for bigger tasks where you can watch it. It did finish the real repo task. Do not leave it unattended on a small task with a verification loop.
- Codex I cannot recommend against a local model at this time. Two runs, zero working pages, and by far the most tokens sent.
Need help building or securing a local AI capability? Email us at Hello At PatriotConsultingTech.com
Sources and references:
- Qwen3.8-Flash-Next on a single DGX Spark (the server recipe): https://github.com/MiaAI-Lab/Qwen3.8-Flash-Next-Single-DGX-Spark
- OpenCode: https://opencode.ai | qwen-code: https://github.com/QwenLM/qwen-code | Claude Code: https://claude.com/claude-code | Codex CLI: https://github.com/openai/codex
- All runs on one DGX Spark (GB10, 119.7 GB usable unified memory), vLLM 0.1.dev20073 with FlashInfer 0.6.17, September 9, 2026. Token counts from vLLM's
/metricsendpoint before and after each run.
About the author. Joe Stocker is the Founder and Chief Technical Officer of Patriot Consulting, a former Microsoft Security MVP (2020-2026), and author of the book "Securing Microsoft 365." In his spare time Joe volunteers with several Microsoft programs including Microsoft's Defending Democracy (AccountGuard) program, Microsoft Tech for Social Impact, and the Microsoft Software and Systems Academy (MSSA), which serves military service members desiring to transition into the civilian workspace.
Note: The author created this article with assistance from AI. Learn more