Partial JSON

Parses incomplete JSON strings streamed token-by-token from an LLM into usable JavaScript values as they arrive.

Library
npm
v0.1.7
244 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
30 /100 Needs Attention
Development Activity 12
Maintenance 0
Community 32
Maturity 48
Momentum 28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
67 /100 Good
Architecture 70
Code Quality 65
Innovation 78
Learning Curve 55

Partial JSON solves a problem specific to streaming LLM output: a model’s structured response arrives one token at a time, so at any point before the final token the JSON is syntactically broken and JSON.parse throws. Partial JSON walks the string with a single recursive-descent pass and returns the best value it can reconstruct from what has streamed so far, so a UI can render an object’s fields as they complete instead of waiting for the whole payload.

Rather than an all-or-nothing “partial mode”, it exposes a bitmask (Allow.STR, Allow.NUM, Allow.ARR, Allow.OBJ, Allow.NULL, Allow.BOOL, Allow.NAN, Allow.INFINITY, Allow._INFINITY) so callers decide exactly which value types are allowed to be incomplete — for example allowing partial strings and objects but requiring numbers to be fully written before they appear. It throws a distinct PartialJSON error when the string is simply unfinished (recoverable, keep streaming) versus MalformedJSON when it’s genuinely invalid, so callers can branch on the two cases instead of treating every parse failure the same way. The library is dependency-free, ships both CommonJS and ESM builds, and is published to both npm and JSR.

What You Get

  • A parse() function that behaves exactly like JSON.parse on complete input, and gracefully degrades on incomplete input
  • Fine-grained Allow bitmask flags to control which value types (strings, numbers, arrays, objects, null/bool, NaN/Infinity) are permitted to be partial
  • Distinct PartialJSON and MalformedJSON error classes so callers can tell “still streaming” apart from “actually broken”
  • Dual CommonJS/ESM builds with bundled TypeScript type declarations, published to both npm and JSR
  • A companion Python implementation (partial-json-parser on PyPI) for teams working across both stacks

Common Use Cases

  • Rendering a structured LLM response (e.g. a tool call or JSON-mode completion) into the UI as it streams, instead of waiting for the full payload
  • Building chat UIs that progressively reveal fields of a streamed JSON object as the model finishes each key
  • Validating and recovering usable data from truncated or cut-off JSON logs and API responses
  • Powering custom streaming parsers layered on top of OpenAI/Anthropic-style token streams

Under The Hood

Architecture The library is a single recursive-descent parser (src/index.ts) built around a closure-based cursor (index/length) that walks the input string once, dispatching on the current character to parseStr/parseObj/parseArr/parseNum/literal matchers; partiality is handled locally in each sub-parser by catching an unexpected end-of-input and, if the corresponding Allow bit is set, returning what was built so far instead of propagating the error. Configuration is isolated into its own module (src/options.ts) as plain bitwise constants composed into higher-level groups (ATOM, COLLECTION, ALL), keeping the parsing logic and the partiality policy cleanly separated despite the whole implementation living in two files.

Tech Stack Written in strict-mode TypeScript targeting ESNext, compiled with tsc to a dist/ output that ships both CommonJS and ESM entry points plus .d.ts declarations. Zero runtime dependencies. Tests run on Vitest with Istanbul coverage; CI (GitHub Actions) builds with Bun, runs the coverage suite, publishes a coverage report to GitHub Pages, and separately publishes the built package to both the npm registry and JSR on tagged releases.

Code Quality A Vitest suite (tests/examples.test.js) exercises the parser against string, array, object, singleton (null/true/false), and numeric edge cases for each Allow flag combination, including several negative cases that assert a specific error type is thrown. Strict TypeScript catches type misuse at compile time, and Prettier enforces consistent formatting, though there is no separate linter (ESLint) configured and the test suite covers behavior rather than exhaustive input fuzzing.

API Design The single-function surface (parse, plus the Allow bitmask and two error classes) mirrors the built-in JSON.parse signature closely enough that adopting it is a near drop-in swap, while the bitmask lets a caller be as permissive or as strict as their use case needs without any additional configuration objects. Naming (Allow.STR, Allow.OBJ, etc.) and the recoverable-vs-fatal error split are documented directly in the source via JSDoc comments that also populate the published type declarations.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers