jsonrepair-rs

Repair malformed JSON-like text and return valid JSON text.
jsonrepair-rs is a Rust library for cleaning up JSON commonly produced by
LLMs, copied from JavaScript/Python/MongoDB contexts, pasted from markdown, or
truncated in transit. It is a Rust port inspired by
josdejong/jsonrepair.
This crate provides both a library API and a small command-line binary.
Installation
Or add it manually:
[]
= "0.2.0"
Minimum supported Rust version: 1.70.
Command Line
Install the binary with Cargo:
Repair stdin to stdout:
|
Repair a file and write the result to another file:
Quick Start
use jsonrepair;
jsonrepair returns a JSON string. If you need typed data, parse the repaired
string with serde_json in your application:
use jsonrepair;
API
| API | Feature | Returns | Failure modes |
|---|---|---|---|
jsonrepair(input) |
default | repaired JSON String |
JsonRepairError when input cannot be repaired safely |
jsonrepair_to_writer(input, writer) |
default | writes repaired JSON to std::io::Write |
JsonRepairWriteError::Repair or JsonRepairWriteError::Write |
jsonrepair_reader_to_writer(reader, writer) |
default | reads from std::io::Read, writes to std::io::Write |
JsonRepairStreamError::Read, Repair, or Write |
jsonrepair_value(input) |
serde |
repaired serde_json::Value |
JsonRepairParseError::Repair or JsonRepairParseError::Parse |
jsonrepair_parse<T>(input) |
serde |
repaired and deserialized T |
JsonRepairParseError::Repair or JsonRepairParseError::Parse |
Supporting types:
JsonRepairErrorcontainsmessage,position,kind,line, andcolumn.JsonRepairErrorKindis a non-exhaustive enum for programmatic repair-error handling.JsonRepairWriteError,JsonRepairStreamError, andJsonRepairParseErrordistinguish repair failures from IO orserde_jsonparse failures.
The output is valid JSON when the function returns Ok(...). When the input
cannot be repaired safely, the function returns an error instead of guessing.
The reader-to-writer API is streaming-oriented at the IO boundary, but the
current parser still buffers complete input and repaired output internally. See
docs/streaming-api.md for the design and memory
tradeoffs.
Repair a file into another file:
use File;
use jsonrepair_reader_to_writer;
What It Repairs
| Input style | Example repair |
|---|---|
| Single, curly, and backtick quotes | {'a': 'b'} -> {"a": "b"} |
| Unquoted object keys | {name: "Ada"} -> {"name": "Ada"} |
| Missing commas | [1 2 3] -> [1, 2, 3] |
| Leading or trailing commas | [1,2,] -> [1,2] |
| Missing colons | {"a" 1} -> {"a": 1} |
| Missing object values | {"a":} -> {"a":null} |
| JavaScript, Python, and case variants | True, False, None, undefined, NaN, Infinity |
| Signed non-finite values | -Infinity, +NaN -> null |
| Comments | //, /* ... */, and # comments are removed |
| Markdown code fences | json ... wrappers are stripped |
| Truncated JSON | missing brackets, braces, strings, and exponents are completed |
| Redundant closing brackets | {"a":1}} -> {"a":1} |
| Number fixes | .5, +.5, 2., 2e, 2e+ |
| Invalid numbers as strings | 0.0.1 -> "0.0.1" |
| String fixes | missing quotes, invalid escapes, unescaped control chars |
| String concatenation | "a" + "b" -> "ab" |
| JSONP | callback({"a":1}); -> {"a":1} |
| MongoDB wrappers | ObjectId("..."), NumberLong("..."), NumberInt(...) |
| NDJSON / root value lists | newline-delimited values become an array |
| URLs and regex-like tokens | unquoted URL and regex-like text become strings |
| Ellipsis placeholders | [1, 2, ...] -> [1, 2] |
| BOM and special whitespace | normalized outside strings |
The test suite contains many edge cases for these categories in
tests/repair_tests.rs.
Error Handling
use ;
match jsonrepair
Error kinds are marked #[non_exhaustive]; include a fallback arm when matching
them outside this crate.
Limits And Behavior
- Maximum supported nesting depth is 512.
- The crate preserves much of the original whitespace where possible.
- It returns a repaired JSON string, not a
serde_json::Value. - The
jsonrepair_reader_to_writerAPI supports reader-to-writer workflows, but0.2.0still buffers internally instead of performing constant-memory repair. - It is designed for practical repair, not for accepting arbitrary unsafe input as if it were trustworthy. Validate the repaired data according to your application's schema before using it.
Examples
Runnable examples live in examples/:
repair_basic repairs and prints a malformed JSON-like string.
repair_and_parse repairs a string and then parses it with serde_json.
Feature Flags
| Feature | Default | Notes |
|---|---|---|
serde |
No | Enables optional serde and serde_json dependencies plus repair-and-parse helpers. |
For most applications, add serde_json directly to your own Cargo.toml if you
want to parse the repaired string into typed data.
With the serde feature enabled, the crate also provides convenience helpers
for repair-and-parse workflows:
use jsonrepair_value;
Development
CI-equivalent local checks:
RUSTFLAGS="-Dwarnings"
The GitHub Actions workflow runs check, formatting, tests, and docs on main
pushes and pull requests.
Pre-commit Hooks
Benchmarks
Run Criterion benchmarks:
Current benchmark groups cover:
- valid small JSON
- broken small JSON
- valid 1k-item JSON
- broken 1k-item JSON
- 100-level nesting
- 100 comments
- 200 string escapes
For optimization work, use the benchmark gate script with an existing Criterion baseline:
The script runs:
cargo fmtcargo check --all-targetscargo clippy --all-targets --all-features -- -D warningscargo test --all-targets- Criterion benchmarks against the selected baseline
- Stable regression detection with optional reruns and a control self-check
Useful options:
Reports are written to .omx/reports/opt-round-<timestamp>.md by default. If
the benchmark environment is too noisy to trust, the script exits inconclusive
instead of reporting a false regression.
Release Status
This branch prepares 0.2.0. The latest crate published on crates.io remains
0.1.1 until the release is published.
To publish a new release, first bump the version in Cargo.toml and update any
version references in this README. Then follow
docs/release-checklist.md. The minimum local
gate is:
RUSTFLAGS="-Dwarnings"
If the dry run succeeds, publish with cargo publish and create a matching git
tag/release.
License
MIT. See LICENSE.