json-repair review
json-repair 0.63.4 turns several common forms of malformed JSON into either Python values or corrected JSON text. It handles unfinished containers, missing separators or quotes, comments, surrounding prose, truncated strings, and some Python-style literals. Valid input takes the standard json.loads path first. The new 0.63.4 patch preserves leading quote characters when a later valid delimiter closes the string. Our lab measurement covers 0.63.3, which installed as a typed pure-Python package and imported successfully.
json-repair 0.63.3 installed in 0.2 seconds and used 1 MB in our sandbox with zero audit findings; 0.63.4 adds one string-delimiter fix beyond that run. Use it as a logged recovery layer, then validate the repaired object before any consequential action.
We installed it
| Install | ✓ · 0.2s | 1 package on disk · 1 MB |
| Import | ✓ | import json_repair in 0.20s · pure Python · py.typed · requires Python >=3.10 |
| Known vulns | 0 | (pip-audit) |
Answers from our run
Does json-repair install cleanly?
Yes. In a fresh container with an empty cache, pip install json-repair finished in 0.2s, leaving 1 package and 1 MB on disk. pip-audit reported no known vulnerabilities.
What does json-repair need to run?
Python >=3.10, and nothing compiled: it is pure Python. In our run import json_repair succeeded in 0.20s, and the package ships py.typed for type checkers.
json-repair or json5: which should you use?
json5: Use it when the input follows the known JSON5 grammar rather than being accidentally damaged. json-repair 0.63.3 installed in 0.2 seconds and used 1 MB in our sandbox with zero audit findings; 0.63.4 adds one string-delimiter fix beyond that run.
When should you not use json-repair?
You control generation and can require tool calls, constrained decoding, or JSON Schema output. Prevention avoids guessed values.
Use it if
- Model or API output is almost JSON and the upstream system cannot enforce a schema before returning it.
- A backlog of malformed logs or scraped values must be recovered after the producer is already gone.
- A growing model-response buffer needs stable partial rendering through stream_stable.
- Valid payloads should use the standard parser before repair heuristics are attempted.
- You control generation and can require tool calls, constrained decoding, or JSON Schema output. Prevention avoids guessed values.
- Silently inserting nulls, empty strings, closing characters, or dropping damaged content would be worse than rejecting the record.
- Inputs are valid and throughput is the only concern. The repair path is a Python character parser, so json or orjson is a better fit.
- Schema-guided output must have a settled API. The project labels that mode beta and says to expect bugs.
- A large stream needs true incremental work per chunk. stream_stable reparses the accumulated text on each call.
Setup reality
We installed json-repair 0.63.3, the measured release, in a clean Python 3.12 Bookworm container in 0.2 seconds. It left one package and 1 MB on disk. The package metadata declared two direct dependencies, Python 3.10 or newer, pure Python code, and a py.typed marker. import json_repair completed in 0.20 seconds. pip-audit found zero known vulnerabilities. Its license value was unknown in our package inspection.
PyPI now serves 0.63.4, one patch newer than our sandbox run. That release fixes preservation of leading quotes when a later delimiter closes a string. The distribution name is json-repair, while imports and the CLI use json_repair. loads returns a Python value; repair_json returns text unless return_objects is true. Empty text can represent an unrecoverable input, so callers must check it.
Installing the schema extra adds Pydantic and jsonschema support. Supplying a schema processes valid and broken input alike, can coerce values or remove forbidden properties, and cannot be combined with strict mode. Salvage requires a schema and may discard invalid items. Run the consumer's own validator after repair before storage, billing, permissions, or deletion.
stream_stable makes repeated parses of a growing buffer less jumpy, but it does not retain parser state. Throttle calls for long streams. logging changes the return value to an object-and-log tuple. Set ensure_ascii false when repaired text must preserve non-ASCII characters. File helpers still surface missing-path and permission exceptions, which should remain separate from parse failures.
Patterns
Return a Python object from broken JSON parse-malformed-json
import json_repair
data = json_repair.loads('{"users":[{"name":"Ada",}],"ok":true')loads already tries json.loads first, so wrapping it in another standard-parser attempt repeats the same check.
Emit corrected readable JSON repair-json-text
from json_repair import repair_json
fixed = repair_json(raw, indent=2, ensure_ascii=False)
if not fixed:
raise ValueError('unrecoverable JSON')An empty string can mean the parser found nothing usable; check before handing text to another service.
Avoid serializing the repaired value return-object
data = repair_json(raw, return_objects=True)Use return_objects or loads when Python code needs the value and no corrected JSON string is required.
Bypass the valid-JSON fast path skip-known-invalid-check
data = repair_json(known_bad, return_objects=True, skip_json_loads=True)Only use this for known-invalid data. The repair parser can alter a valid value that json.loads would preserve.
Capture a repair log audit-repairs
data, repairs = repair_json(raw, return_objects=True, logging=True)
if repairs:
logger.warning('JSON repaired', extra={'repairs': repairs})logging true changes the return type to a two-item tuple, which should be hidden behind one application helper.
Raise instead of guessing reject-ambiguous-input
try:
data = json_repair.loads(raw, strict=True)
except ValueError as error:
quarantine(raw, str(error))Strict mode rejects duplicate keys, missing separators, empty keys or values, and multiple top-level elements.
Guide recovery with JSON Schema repair-with-schema
schema = {'type': 'object', 'properties': {'value': {'type': 'integer'}}, 'required': ['value']}
data = repair_json('{"value": "1"}', schema=schema, return_objects=True)Install json-repair with its schema extra. Schema processing applies even when the incoming JSON is valid.
Render a throttled partial buffer repair-growing-stream
buffer = ''
for chunk in stream:
buffer += chunk
if should_refresh():
render(json_repair.loads(buffer, stream_stable=True))Every refresh parses the accumulated buffer again; throttling prevents repeated work on each token or byte.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| json5 | PyPI | Use it when the input follows the known JSON5 grammar rather than being accidentally damaged. |
| dirtyjson | PyPI | Use it for predictable extensions such as comments, single quotes, trailing commas, and bare keys. |
| demjson3 | PyPI | Use it when tolerant JavaScript-style decoding is the requirement and heuristic completion is not. |
More utils guides
lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →
How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.

