partial-json review
partial-json 0.1.7 recovers the JavaScript value already implied by a JSON string that ends early. An object can stop inside a nested array or quoted value and still yield completed fields plus any unfinished types allowed by a bitmask. The mask controls strings, numbers, arrays, objects, booleans, null, NaN, and positive or negative Infinity. This is a text parser, not an LLM or validation layer, even though streamed model output is its main example. Version 0.1.7 corrects parsing when truncation lands in an escape sequence and adds detail to its bundled TypeScript declarations. Our browser bundle was 4.2 KB minified and 1.7 KB gzipped.
partial-json 0.1.7 installed as 1 package and 1 MB in our sandbox, bundled to 1.7 KB gzipped, and returned 0 audit findings. It is a good preview parser for one incomplete JSON document, provided the finished payload still passes strict parsing and schema checks before it affects anything durable.
We installed it
| Install | ✓ · 0.5s | 1 package on disk · 1 MB |
| Import | ✓ | ESM import works · require() works · CommonJS package with exports map |
| Browser | 1.7 KB | gzipped (4.2 KB minified), bundled with esbuild |
| Types | ✓ | TypeScript types bundled |
| Known vulns | 0 | 0 critical · 0 high · 0 moderate · 0 low (npm audit) |
Answers from our run
Does partial-json install cleanly?
Yes. In a fresh container with an empty cache, npm install partial-json finished in 0.5s, leaving 1 package and 1 MB on disk. npm audit reported no known vulnerabilities.
How much does partial-json add to a browser bundle?
1.7 KB gzipped (4.2 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.
Does partial-json work with both ESM and CommonJS?
Yes. Both import 'partial-json' and require('partial-json') worked in Node 22 in our run. The package is published as CommonJS with an exports map.
Does partial-json include TypeScript types?
Yes, type declarations ship inside the package, so no @types install is needed.
partial-json or jsonrepair: which should you use?
jsonrepair: Choose it when a complete document contains broken JSON syntax that should be rewritten into valid JSON text. partial-json 0.1.7 installed as 1 package and 1 MB in our sandbox, bundled to 1.7 KB gzipped, and returned 0 audit findings.
When should you not use partial-json?
Use jsonrepair for misplaced commas, comments, single quotes, or other damaged syntax. partial-json throws MalformedJSON when the text cannot be a valid prefix.
Use it if
- A screen should render finished fields while the closing bytes of one JSON document are still arriving.
- A model response can hit a token limit and the application wants completed properties without pretending the document is valid.
- Different consumers need explicit rules about which unfinished scalar or container types may appear in previews.
- One parser call should accept the final JSON document as well as its earlier prefixes.
- Use jsonrepair for misplaced commas, comments, single quotes, or other damaged syntax. partial-json throws MalformedJSON when the text cannot be a valid prefix.
- Use an evented parser such as clarinet for a very large stream. partial-json has no feed method and reparses the supplied accumulated string on each call.
- Strict JSON values are mandatory at every step. The default Allow.ALL policy accepts partial literals plus NaN and Infinity, which JSON.parse rejects.
- A number must remain invisible until its last digit arrives. Allow.NUM may expose 1, then 10, then 100 as successive versions of the same field.
- Do not place a 0.x recovery parser on an authorization, billing, or persistence boundary. The final bytes still require JSON.parse and schema validation.
Setup reality
We installed partial-json 0.1.7 in 0.5 seconds in a fresh Node 22 Bookworm sandbox. npm placed 1 package and 1 MB on disk. The published package contains 0 direct dependencies, 0 peer dependencies, and 56 KB unpacked. npm audit reported 0 known vulnerabilities. TypeScript declarations are included. require and ESM import both succeeded through its CommonJS build and exports map. Our browser build came to 4.2 KB minified and 1.7 KB gzipped.
There are no credentials, native modules, service processes, or configuration files. The real configuration is the Allow bitmask passed to parse. Omitting it selects Allow.ALL, which may return unfinished strings, numbers, containers, literal prefixes, NaN, and Infinity as soon as the parser can infer a value. Define the narrowest preview policy in one place rather than scattering different masks through UI components.
Keep the full text received so far, append each chunk, and call parse again. partial-json has no stateful parser object, so every update scans the supplied buffer from the beginning. PartialJSON means the current prefix cannot satisfy your chosen allowance yet. MalformedJSON means the grammar has gone wrong. Type errors and the empty-input error are separate caller failures and should not be swallowed by a broad parser catch.
Intermediate values can change. Allow.NUM may turn 12 into 123 on the next chunk, and Allow.BOOL can infer true from a leading t. NaN and Infinity are JavaScript extensions rather than JSON values. Use these results for preview state only. When the stream closes, run JSON.parse on the complete text and validate the returned shape before saving data or making a security decision.
Patterns
Parse a finished JSON value parse-complete-value
import { parse } from 'partial-json';
const value = parse('{"ready": true, "count": 2}');
console.log(value.ready);A complete standard document returns the same value shape expected from JSON.parse.
Recover an unfinished nested string parse-default-prefix
import { parse } from 'partial-json';
const value = parse(
'{"title":"Draft","tags":["node","str'
);
// { title: 'Draft', tags: ['node', 'str'] }With no mask, Allow.ALL returns the open string and its unfinished parent containers.
Return containers while withholding open scalars withhold-partial-scalars
import { parse, Allow } from 'partial-json';
const value = parse(
'{"title":"Dra',
Allow.OBJ | Allow.ARR
);
// {}Allow.OBJ permits the incomplete object result. Without Allow.STR, the unfinished title property does not appear.
Define one preview allowance mask combine-allow-flags
import { parse, Allow } from 'partial-json';
const PREVIEW = Allow.OBJ | Allow.ARR | Allow.STR;
const preview = parse(buffer, PREVIEW);This policy returns growing strings and containers while waiting for complete numbers, booleans, null, NaN, and Infinity.
Reparse the buffer after every chunk consume-text-stream
import { parse, Allow, PartialJSON } from 'partial-json';
let buffer = '';
for await (const chunk of textStream) {
buffer += chunk;
try {
render(parse(buffer, Allow.COLLECTION | Allow.STR));
} catch (error) {
if (!(error instanceof PartialJSON)) throw error;
}
}The library stores no parsing state between calls. Pass the entire text accumulated so far on each update.
Distinguish incomplete text from bad grammar separate-parser-errors
import { parse, PartialJSON, MalformedJSON } from 'partial-json';
try {
return parse(text, allowed);
} catch (error) {
if (error instanceof PartialJSON) return previousPreview;
if (error instanceof MalformedJSON) reportBadSyntax(error.message);
throw error;
}TypeError and the empty-input Error are outside the 2 exported parser error classes. Rethrow them as caller defects.
Keep an unfinished number out of the preview delay-partial-number
import { parse, Allow, PartialJSON } from 'partial-json';
try {
parse('12e', Allow.ALL & ~Allow.NUM);
} catch (error) {
console.log(error instanceof PartialJSON);
}Removing Allow.NUM prevents a number prefix from being displayed as though it were the finished value.
Infer boolean and null prefixes accept-partial-literals
import { parse, Allow } from 'partial-json';
parse('t', Allow.BOOL); // true
parse('fa', Allow.BOOL); // false
parse('nu', Allow.NULL); // nullThe parser selects the only matching supported literal. JSON.parse rejects all 3 prefixes until their words are complete.
Allow JavaScript special numbers explicitly control-special-numbers
import { parse, Allow } from 'partial-json';
parse('Inf', Allow.INFINITY); // Infinity
parse('-Inf', Allow._INFINITY); // -Infinity
parse('Na', Allow.NAN); // NaNInfinity and NaN are outside the JSON specification and will not survive a standard JSON serialization round trip.
Load the CommonJS entry load-with-require
const { parse, OBJ, STR } = require('partial-json');
const value = parse('{"name":"Ada', OBJ | STR);require succeeded in our Node 22 check. ESM import resolved through the same package exports map.
Import allowance constants from the option subpath import-option-subpath
import { COLLECTION, STR } from 'partial-json/options';
import { parse } from 'partial-json';
const preview = parse(buffer, COLLECTION | STR);partial-json/options is declared in the exports map and includes matching TypeScript declarations.
Validate the completed document before saving validate-final-document
const finalValue = JSON.parse(buffer);
const result = OutputSchema.safeParse(finalValue);
if (!result.success) {
throw new Error('Final JSON has the wrong shape');
}
await save(result.data);A partial preview proves neither stream completion nor the application's required field shape. Strict parsing and schema validation remain separate gates.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| jsonrepair | npm | Choose it when a complete document contains broken JSON syntax that should be rewritten into valid JSON text. |
| jsonc-parser | npm | Choose it for JSON with comments, tolerant parsing, location data, and editor-style modifications. |
| clarinet | npm | Choose it for SAX-style events from a large stream when retaining and reparsing the whole buffer is undesirable. |
More utils guides
lru-cache · type-fest · ajv · 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.

