mrkeyoor.com_
Sat 08 Aug 22:51 UTC
npmUtilsupdated 08 Aug 2026

jsonrepair

jsonrepair turns many common forms of almost-JSON into valid JSON text. It can quote bare keys, convert single and curly quotes, add commas and closing brackets, remove comments and trailing commas, unwrap Markdown fences or JSONP, convert Python and MongoDB literals, join newline-delimited objects into an array, and salvage truncated input. The regular API is a synchronous string-to-string function; Node also gets a Transform stream and the package includes a CLI. It repairs syntax, not the meaning or schema of the data.

Verdict

One of the best small tools for recovering syntax from human- or model-produced JSON-like text, with a rare streaming implementation and no dependencies. Do not confuse a successful repair with trustworthy data: parse it, validate it, and reject it when strict input is the safer contract.

API stability4/5The v3 root API has stayed compact since the December 2022 rewrite: named jsonrepair and JSONRepairError exports, with jsonrepair/stream added as a separate subpath in 3.5.0. The function and stream signatures are small and typed. Output behavior is less static than the signature, because minor releases add new repair rules and bug fixes; 3.14.1 changed number, quote, and trailing-comma handling, while 3.15.0 added HTML-entity repair. Pin and regression-test ambiguous inputs.
Docs5/5The README lists the exact malformed constructs it can fix, demonstrates ESM, CommonJS, UMD, PythonMonkey, Node streams, and the CLI, and documents both stream options with their 65536-byte defaults. It also states the regular implementation's intended file limit, explains why the stream needs a moving window, and warns about out-of-range errors and memory tradeoffs. The development section even explains that regular and streaming implementations share a test suite.
Maintenance5/5Version 3.15.0 was published on July 3, 2026, and the repository was pushed the same day. The current changelog covers that release and shows sustained feature and bug-fix work through 2024, 2025, and 2026, including a security fix in 3.13.2 and several parser-correctness fixes in 3.14.1. The repository currently reports 18 open issues and PRs, a manageable queue for a parser with many edge cases.
Ecosystem4/5The package recorded 2,979,249 weekly downloads and the repository has 2,392 stars. It supports ESM, CommonJS, a UMD browser build, TypeScript declarations, a Node Transform, and a CLI without runtime dependencies, covering most integration styles. The tradeoff is a deliberately narrow role: it produces valid JSON text but leaves parsing, schema validation, duplicate-key policy, provenance, and application semantics to other tools.

Use it if

  • You receive JSON-like text copied from logs, JavaScript, Python, MongoDB shells, or Markdown and need a best-effort syntactic cleanup
  • You need to turn newline-delimited JSON records into one valid JSON array without writing a custom parser
  • You process a file too large for a single in-memory string and can use the Node streaming transform with an appropriate buffer
  • You want one zero-dependency package that works through ESM, CommonJS, a Node stream, or a command-line pipeline
Skip it if

Setup reality

npm install jsonrepair is the whole package setup: version 3.15.0 has no runtime dependencies, includes TypeScript declarations, and exposes separate ESM and CommonJS entries. Use the named jsonrepair export; the v3 changelog records the old default export as a breaking change. The regular call is synchronous and accepts only a string. It returns another string, not an object, so call JSON.parse yourself and then run schema validation if the result enters application logic. Unrepairable input throws JSONRepairError with a zero-based position. In a browser, the regular implementation keeps the document in memory; the README says it is intended for files up to 512 MB, but your actual memory ceiling may be lower because both input and generated output coexist. Node's jsonrepair/stream subpath exposes a Transform and is the right choice for large or unbounded input. Its default chunkSize and bufferSize are both 65536 bytes. chunkSize controls emitted chunks, while bufferSize is a moving window used for look-ahead and output rewrites. bufferSize must exceed the longest string, number, and whitespace run in the document; increasing it costs memory and can reduce performance, while an infinite buffer removes the window limit but can exhaust memory. The CLI reads a filename or stdin and writes to stdout unless --output is given. --overwrite modifies the source file, so keep it out of automated cleanup until you have backups and tests. Machine-generated or user-submitted text still needs size limits, time limits, JSON.parse, and schema validation after repair. Current versions matter: the changelog records a security fix in 3.13.2 for an XSS risk in regex repair, so do not copy an old lockfile version into a browser-facing path.

Patterns

Quote keys and convert single-quoted stringsrepair-json-like-text

import { jsonrepair } from 'jsonrepair';

const input = "{name: 'Ada', role: 'admin'}";
const repaired = jsonrepair(input);
console.log(repaired); // {"name": "Ada", "role": "admin"}

The return value is JSON text. jsonrepair does not parse it into an object or check whether role is an allowed application value.

Repair, parse, then validate separatelyrepair-and-parse

import { jsonrepair } from 'jsonrepair';

const repaired = jsonrepair(rawText);
const value = JSON.parse(repaired);

if (!value || typeof value !== 'object' || typeof value.id !== 'string') {
  throw new TypeError('Expected an object with a string id');
}

Syntax repair and data validation are different steps. Use a schema validator for nested production payloads instead of growing manual checks.

Convert Python constants and trailing commasconvert-python-literals

const repaired = jsonrepair(
  "{name: 'Ada', active: True, note: None,}",
);

console.log(repaired);
// {"name":"Ada", "active": true, "note": null}

True, False, and None are mapped to JSON booleans and null. Other Python expressions are not evaluated.

Close a truncated object or arrayfinish-truncated-json

const repaired = jsonrepair('{"items":[1,2,3');
console.log(repaired); // {"items":[1,2,3]}

Closing syntax can be inferred, but missing content cannot. Treat a repaired truncated response as partial data unless the schema proves otherwise.

Remove a fenced Markdown wrapperunwrap-markdown-json

const ticks = String.fromCharCode(96).repeat(3);
const response = `${ticks}json\n{answer: 42}\n${ticks}`;

const repaired = jsonrepair(response);
const data = JSON.parse(repaired);

Fence repair was added during the v3 line and handles optional language labels such as json. Text outside the fenced JSON can still make the input unrepairable.

Turn newline-delimited objects into an arrayconvert-ndjson-array

const ndjson = [
  '{"id":1,"name":"Ada"}',
  '{"id":2,"name":"Linus"}',
].join('\n');

const rows = JSON.parse(jsonrepair(ndjson));
console.log(rows.length); // 2

The result is one array string, so the regular API still holds the full converted document in memory. Use the stream for a large source.

Strip common MongoDB shell constructorsnormalize-mongodb-values

const input =
  '{created: ISODate("2012-12-19T06:01:17.171Z"), count: NumberLong(2)}';

console.log(jsonrepair(input));
// {"created": "2012-12-19T06:01:17.171Z", "count": 2}

The ISODate wrapper becomes a string, not a JavaScript Date. Convert and validate dates after JSON.parse if the application needs Date objects.

Report an unrepairable positionhandle-repair-errors

import { jsonrepair, JSONRepairError } from 'jsonrepair';

try {
  return jsonrepair(input);
} catch (error) {
  if (error instanceof JSONRepairError) {
    console.error('Could not repair at offset', error.position);
  }
  throw error;
}

position is a zero-based string offset. It is not a line and column pair, so calculate those separately when presenting an editor diagnostic.

Repair a file through a Node streamstream-large-file

import { createReadStream, createWriteStream } from 'node:fs';
import { pipeline } from 'node:stream/promises';
import { jsonrepairTransform } from 'jsonrepair/stream';

await pipeline(
  createReadStream('./broken.json'),
  jsonrepairTransform(),
  createWriteStream('./repaired.json'),
);

Import from jsonrepair/stream, not the root. pipeline propagates read, transform, and write errors and closes the connected streams.

Increase the moving window for long tokenstune-stream-buffer

const repair = jsonrepairTransform({
  bufferSize: 1024 * 1024,
  chunkSize: 64 * 1024,
});

await pipeline(inputStream, repair, outputStream);

bufferSize must exceed the longest string, number, or whitespace run. A larger window uses more memory and can reduce performance; chunkSize only controls emitted chunk size.

Use the CLI in a shell pipelinerepair-from-stdin

npm install --global jsonrepair@3.15.0
cat broken.json | jsonrepair > repaired.json

The CLI streams stdin to stdout. Check the command's exit status before replacing or consuming the generated file in automation.

Write a repaired file or replace the inputrepair-file-output

jsonrepair broken.json --output repaired.json

# Destructive: only after reviewing or backing up the source
jsonrepair broken.json --overwrite

--output keeps the original and is the safer default. --overwrite replaces the input file, so a bad heuristic choice can destroy the evidence needed to repair it manually.

Alternatives

PackageRegistryPick it when
dirty-jsonnpmYou want a permissive parser that returns a JavaScript value directly from messy JSON-like text
json5npmYou control the input format and want a documented relaxed JSON syntax rather than heuristic repair
jsonc-parsernpmYou need comments, trailing commas, parse errors, and edit operations for configuration files or an editor
ajvnpmYour text is already valid JSON and the real requirement is JSON Schema validation