JSON.parse is all-or-nothing. It needs a balanced document before it returns anything, so until the closing brace arrives you have nothing to show (a write-up on streaming JSON parsers puts it plainly: partial input is not a state the standard parser models, it is "input error"). That is a fine contract for an HTTP body with a known content length. It is the wrong contract for a token stream, where the document is legitimately incomplete for most of its life.
Teams usually hit this in one of two ways. The first is to wait for the closing brace and parse once. That works, but the user stares at a spinner for the entire generation, and the perceived-latency cost is real: one measurement cited in that same write-up puts the improvement from progressive rendering at roughly 60 to 70 percent, not because the response got faster but because the waiting changed shape.
The second is worse. Teams keep buffering but call JSON.parse (or a repair library) on every chunk to "see what we have so far." That re-parses the whole prefix on every token, which is O(n²) work. The same write-up reports a naive implementation taking 16.7 seconds on a 12 KB document with final chunks costing 19 to 20 milliseconds each, against 43 milliseconds for a stateful incremental parser on the same workload. The naive version became unusable around the 5 KB mark. If you already have a repair step in your pipeline, it is the right tool for a dropped connection and the wrong tool for the hot path.
Before you write a parser, check whether the model is constrained in the first place. Constrained decoding masks invalid tokens at generation time so the output is valid by construction, and the ZeroEntropy explainer notes that parse-error rates of 1 to 5 percent are common when you rely on prompting alone (constrained decoding overview). If your provider supports schema-constrained output, turn it on. A partial parser is still needed for rendering, but it is no longer a correctness crutch.



