Toolkit Labs

the full leaderboard

11 Python JSON parsers on 300 broken outputs

Every library below was given the same 300 labelled model outputs and graded on whether it returned the expected value — not repaired text, not a best guess that looked plausible. 275 of the 300 are recoverable; the other 25 are unrecoverable by construction and the expected answer there is a refusal. Both facts matter, and the second one is why a table of one number would mislead you.

Corpus: MALFORMED-300, sha256 ded36c275f9ff481a9e264f9e900ccbb16da9cf430ff6fe8ffc23b9c02acb88a. Python measured 2026-08-19T12:31:18Z on Python 3.12.3; JavaScript 2026-08-19T12:33:03Z on node v25.8.2. One run per library, nothing tuned afterwards. Both raw run files are published: leaderboard.json · leaderboard_js.json.

libraryexact matches, all 300of the 275 recoverablecorrectly refusedinvented a valuefalse refusalsrun time
jsonshim (Toolkit Labs)282 / 300262 / 27520 / 25540.01 s
json-repair 0.63.2265 / 300264 / 2751 / 252400.01 s
dirtyjson 1.0.8123 / 30098 / 27525 / 2501770.01 s
json5 0.15.0118 / 30093 / 27525 / 2501820.11 s
pyjson5 2.0.1118 / 30093 / 27525 / 2501820.00 s
demjson3 3.0.5110 / 30085 / 27525 / 2501900.06 s
hjson 3.1.085 / 30075 / 27510 / 25151850.01 s
commentjson 0.9.058 / 30033 / 27525 / 2502420.03 s
partial-json-parser 0.2.1.1.post747 / 30025 / 27522 / 2532500.00 s
simplejson 4.1.129 / 3004 / 27525 / 2502710.00 s
json.loads (stdlib control)25 / 3000 / 27525 / 2502750.00 s

“Invented a value” counts the 25 unrecoverable cases where the library returned something instead of refusing. “False refusals” counts recoverable cases it gave up on. A library can score well on the first column and still be the wrong choice if the second-to-last one is large for your pipeline.

What the table says

The stdlib control, json.loads, recovers 25 of 300: those are the cases that were never broken in the first place. Two libraries are in a different band from the rest — json-repair at 265 of 300 and the tool published here at 282 of 300 — and the eight below them cluster between 25 and 123 of 300, because they are dialect parsers doing a different job: they read JSON5, HJSON or commented JSON, and most malformed LLM output is not a dialect, it is damage.

Read the two right-hand columns before choosing. On the 25 unrecoverable cases json-repair returns a value 24 times; the tool here does it 5 times and refuses 20 of 25 — and it also refuses 4 recoverable cases it should have parsed, which is the price of that caution and is not hidden here.

Which one to install

If you want the highest recovery from a package with a large user base and a long history, that is json-repair, and this page does not ask you to pick anything else. If a wrong value costs you more than a refusal does — a write path, a billing field, an eval harness — the column to sort on is “invented a value”, and there the ordering is different. If you are on JavaScript, the same corpus was run there too and the answer is not the same: the full grid holds both, and json-repair vs jsonrepair is the pair most people confuse.

Two failure modes have their own pages because they behave unlike the rest: a stream that stopped mid-object and JSON wrapped in a code fence or in prose.

Check it yourself

The whole run is published, per library and per case, and the scorer is CC0.

curl -O https://toolkitlabs.org/malformed300/open12.jsonl
curl -O https://toolkitlabs.org/malformed300/score.py
python3 score.py --corpus open12.jsonl --parser yourmodule:recover

leaderboard.json is the raw run behind this table · run_leaderboard.py is the harness that wrote it.

What this page does not tell you

The full corpus

The 12 open cases and the scorer are CC0 forever, bought or not. The paid product is the remaining 270 labelled cases with the rationale for each label — what lets you run this measurement on your own parser at full resolution.

Single developer — €29 · Team / CI licence — €99

Instant download after payment; digital goods, delivered immediately. Payments processed by Stripe. Prices include VAT where applicable.