It repairs syntax, not meaning
json_repair handles the mistakes that appear when JSON is typed, streamed, logged, or generated by a model: missing quotes, commas, brackets, values, and stray prose. Its loads() function can stand in for json.loads(). Valid input goes through Python's standard parser first, while invalid input falls back to the repair parser. That design gives ordinary JSON the familiar behavior and reserves heuristics for strings that would otherwise be rejected.
The distinction between syntax and meaning should drive every adoption decision. If a payload says quantity: with no value, a repair tool may produce valid JSON, but it cannot know whether the intended value was zero, null, or omitted. The output belongs in a validation step, not directly in a payment, permission, or deletion path. json_repair is best at salvaging transport shape so an application can inspect the result and make its own decision.
The default path protects valid JSON from repair guesses
The README calls out a common wasteful pattern: try json.loads(), catch its exception, then call json_repair. The library already performs that strict first attempt. A single json_repair.loads() call returns valid JSON through the standard library and invokes repair only after parsing fails. return_objects=True avoids serializing the repaired Python object back into a JSON string when the caller needs data rather than text.
skip_json_loads=True changes that contract. It sends input straight to the repair parser and can help when the caller knows every value is malformed. The documentation warns that valid JSON can then be changed in structure or value. That makes the option unsuitable as a blanket speed switch. Mixed traffic should keep the default. A pipeline that marks known-bad model fragments separately can use the shortcut only on that branch.
Non-Latin output has another explicit switch. Passing ensure_ascii=False preserves Chinese, Japanese, Korean, and other characters instead of emitting Unicode escape sequences. File helpers mirror json.load(), while I/O errors remain the caller's job. These are sensible boundaries: the package repairs JSON structure and leaves file availability, encoding policy, and downstream validation to the application.
What happened when we ran it
Our sandbox installed 34 packages in 24 seconds and consumed 36 MB. The build completed in 10 seconds. At commit c1a431f, the repository had 87 files, roughly 9,989 lines of source, and a 3.2 MB checkout. pip-audit found zero known vulnerabilities. This was the smallest dependency and disk footprint among the Python projects in this review batch.
Tests exited 1 after 9 seconds. pytest reported 222 passed, 6 failed, and 92 skipped out of 228. All six named failures came from schema parsing or repair tests and ended with the same message: ValueError: jsonschema is required when using schema-aware repair. The log does not show a core parser failure. It also does not prove why the optional dependency was absent, so the narrow finding is that the checked-out development setup did not run every schema test successfully in our fresh container.
The result supports a split judgment. Core repair has a substantial passing suite and a clean audit in our environment. Schema use deserves a separate install and test gate. Before shipping that mode, install json-repair[schema], rerun the relevant tests, and try representative schemas from the application. Do not use the 222 passing tests to erase the six failures, and do not use the six optional-path failures to dismiss the core parser.
Strict mode is for rejection, while schema mode is for recovery
Default mode tries hard to return something useful. Strict mode instead raises ValueError on duplicate keys, missing separators, empty keys or values, multiple top-level elements, and other ambiguous structures. It is a better fit when the caller wants clearer errors but must not accept guessed structure. Strict mode can still skip the initial standard parser, though most applications should keep the ordinary validation path.
Schema-guided repair takes the opposite approach. Given JSON Schema or a Pydantic v2 model, it can fill allowed defaults, coerce selected scalars, and drop disallowed properties. Its salvage mode can discard invalid array items or map a clear array shape into an object. The README labels this feature beta, says bugs are expected, and makes it mutually exclusive with strict mode. Those rules should be visible in application configuration rather than buried in a helper function.
Streaming support uses stream_stable=True to keep partial output repairable as more text arrives. This can help a UI display evolving model output, but partial validity should remain provisional. A closing chunk may change the structure or reveal that an earlier guessed value was wrong. Persist only the final validated object unless the product explicitly models partial state.
The project is current and unusually candid about unsafe shortcuts
Version 0.63.4 was released on August 25, 2026, the same date as the latest repository push. GitHub showed no open issues or pull requests. The README documents the dangerous cases directly: valid input can change when forced through repair, schema behavior is beta, strict and schema modes conflict, and inline CLI use overwrites files. That candor is more useful than a promise that every malformed string can be recovered.
Choose json_repair when invalid JSON is common enough to justify a shared, tested fallback. JSON5 is better for a known permissive syntax, Pydantic is better once data already parses, and the JavaScript jsonrepair project fits Node.js. In Python, this package earns a place between raw input and validation. It should not sit between validation and a consequential side effect.

