Repository navigation
Not a Validator
The printer tracks three things: whether it is inside a string, whether the next character is escaped, and which brackets are open. Everything else is copied through. That makes it tolerant of input a parser would reject, and it means the output for broken input is tidy rather than an error. The examples below are the actual output of 3.0.2 (the same as 3.0.1) with the default options.
A trailing comma stays, and the line break it owes goes before the closing brace:
{"a":1,}
{
"a": 1,
}
Single-quoted strings are tracked like double-quoted ones, so the space inside stays:
{'a':'b c'}
{
'a': 'b c'
}
Bare words are just characters:
{a:1,b:[x,y]}
{
a: 1,
b: [
x,
y
]
}
A document that ends before its closing bracket is printed as far as it goes, and an unterminated string swallows whatever follows it:
{"a":1
{
"a": 1
Two documents in one string, as in a JSON Lines file, run together, because the line break between them is whitespace:
{"a":1}
{"b":2}
{
"a": 1
}{
"b": 2
}
Split the lines first and format each one.
A block comment survives, minus its inner spaces:
{"a":1 /* note */,"b":2}
{
"a": 1/*note*/,
"b": 2
}
A // comment is not whitespace, so its characters are copied, but the spaces inside it and the line break that ends it are whitespace and are dropped. The text after the comment is glued onto it:
{"a":1, // a note about a
"b":2}
{
"a": 1,
//anoteabouta"b": 2
}
The output is no longer the document you had. If the input may contain comments, strip them first with System.Text.Json, which drops trailing commas at the same time:
using System.Text.Json;
using System.Text.Json.Nodes;
var lenient = new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true };
var clean = JsonNode.Parse(text, null, lenient)!.ToJsonString(); // compact, comment-free
var pretty = clean.PrettyPrintJson();The printer throws for exactly two things, both FormatException, both naming the zero-based character index in the input as given:
| Input | Message |
|---|---|
{"a":1}} |
Unexpected '}' at index 7: there is no open object or array to close. |
] |
Unexpected ']' at index 0: there is no open object or array to close. |
[1} |
Unexpected '}' at index 2: expected ']'. |
{"a":1] |
Unexpected ']' at index 6: expected '}'. |
A printer that has thrown is fine to reuse; its state is reset at the start of the next call. With the TextWriter overloads, everything before the bad bracket has already been written when the exception arrives.
Null input throws ArgumentNullException, and that is the whole list.
A missing bracket, an unterminated string, a bad escape, a bare word, a duplicate key, a trailing comma: none of these is reported. To know whether text is JSON, parse it first; Recipes shows the short version. The printer is for making text readable, including text that is almost JSON, such as a log line or a config file once its comments are gone.
This wiki describes JsonPrettyPrinter 3.0.2 and was last updated on 2026-09-30. The library is MIT licensed. Report problems in the issues.
Using it
- Getting started
- API reference
- Output format
- Not a validator
- Serialisation helpers
- Recipes
- Performance and threading
- FAQ
The releases
Contributing
Elsewhere