JSON Stringify

Nothing you enter here is stored, logged or shared.

Turn a JSON document into an escaped string you can paste into code, or reverse an escaped string back into readable JSON.

How to use

  1. Choose stringify to escape, or unstringify to reverse it.
  2. Paste your JSON into the input field.
  3. Copy the result with the copy button.

What escaping actually does

Stringify parses your JSON, minifies it, then wraps the result in double quotes and escapes everything that would otherwise end the string early. Internal double quotes become \", backslashes double to \\, and the control characters below U+0020 become their short forms \n, \r, \t, \b and \f, or a \u00XX escape where no short form exists.

Two things are deliberately left alone. The forward slash is not escaped, because JSON does not require it; you will sometimes see \/ in output from other tools, which is legal but unnecessary and comes from an old habit of hiding the sequence </script> inside HTML. Non-ASCII characters are also left as themselves rather than converted to \u escapes, so accented text, CJK and emoji stay readable. Both forms mean the same thing to a parser, and the readable one is easier to diff.

Double encoding, and why it bites

The reason this tool exists is that escaping is not idempotent, and people usually discover this halfway through debugging something else. Escape a document once and a quote becomes \". Escape the result again and it becomes \\\", because the backslash you just added is itself now a character that needs escaping. Each pass roughly doubles the backslashes.

This is the fingerprint of a payload that was serialised twice: a field that should hold an object holds a string of JSON instead, and its quotes are visibly backslashed when you read the log. It happens when code calls a serialiser on a value that some framework already serialised, and the fix is almost always to remove one of the two calls rather than to add a decoding step.

Unstringify is the tool for unwinding it. Run it once per layer of encoding and watch the backslashes halve each time. When they are gone and the result parses as an object, you have found how many layers there were.

Where an escaped string is what you need

Embedding a payload in another JSON document, which is how webhook envelopes, job queues and audit logs usually carry an arbitrary body. Setting an environment variable to a JSON value, where the shell will otherwise eat the quotes. Pasting a request body into a YAML file for a CI job. Writing a test fixture as a literal in source code. Storing a document in a text column rather than a native JSON column.

In each case the inner quotes have to survive a layer of parsing that would otherwise treat them as terminators, and escaping is what carries them through intact.

The escape rules, one character at a time

JSON defines exactly which characters cannot appear literally inside a string. The double quote would end the string early, so it becomes \". The backslash starts an escape, so it doubles to \\. Every control character below U+0020 is forbidden, and five of them have short forms: newline is \n, carriage return \r, tab \t, backspace \b and form feed \f. Everything else in that range becomes a six-character escape such as \u0000.

Two characters are commonly escaped without being required to be. The forward slash may be written \/, which is legal and unnecessary; the habit comes from embedding JSON inside HTML, where the sequence </script> would otherwise end the script element early. Non-ASCII characters may be written as \u escapes, which some libraries do by default to keep output in pure ASCII.

This tool leaves both alone, because readable output diffs better and every parser treats the two forms identically. If a downstream system genuinely needs ASCII-only output, that is a flag on the serialiser rather than something the document requires.

Getting JSON safely through a shell

The shell is where escaping most often goes wrong, because two layers of quoting apply at once. Single quotes in bash pass everything through literally, which is why curl -d '{"name":"value"}' works and the same string in double quotes does not - the shell expands variables and strips characters before curl ever sees them.

When the payload itself contains a single quote, the single-quoted form breaks too, and the robust answer is to stop embedding it in the command line: write the body to a file and use curl -d @body.json, or pipe it in. For generated payloads, jq -n is safer than string concatenation because it produces valid JSON by construction.

Environment variables holding JSON are the related case, particularly in CI configuration and Docker. The value usually needs to survive YAML quoting, shell expansion and the application's own parsing, which is three layers, and the way to keep it sane is to base64-encode the JSON, pass that, and decode at the point of use.

Structured logs and the double-encoding fingerprint

Log pipelines increasingly expect one JSON object per line, which makes fields searchable instead of forcing regular expressions over free text. The trap is logging an object that has already been serialised: the field arrives as a string of JSON rather than as a nested object, and the log system indexes it as one opaque blob.

The visible sign is exactly the fingerprint this tool exists to unwind - a value that reads as {\"id\":42} rather than {"id":42}. Every extra layer roughly doubles the backslashes, so counting them tells you how many encodings happened.

The fix belongs at the producer. Pass the object to the logger and let it serialise once, rather than serialising yourself and passing a string. Where the string arrives from elsewhere and cannot be changed, most log platforms have a JSON parsing filter that can unwrap the field at ingest, which is better than doing it in every query.

Embedding a payload inside another document

Webhook envelopes, job queues and audit logs all face the same problem: a wrapper with its own fields has to carry an arbitrary body. Serialising that body to a string is the simple answer, and the cost is that the inner document becomes opaque - it cannot be queried, validated or indexed without being parsed a second time.

The alternative, keeping the body as a nested object, keeps it queryable but requires the wrapper's schema to allow arbitrary structure and merges the two namespaces in the eyes of anything walking the document. Most systems end up choosing per use: nested where the body is inspected, stringified where it is only relayed.

There is a third option worth remembering when the payload is large or binary: put it somewhere else and send a reference. A URL and a checksum in the envelope avoids both the escaping and the size limit, and it is how most large-file workflows end up working anyway.

Reading escaped text without a tool

Unwinding an encoding by eye is feasible for short values and worth practising, because it tells you what happened. A single layer shows \" around keys and values. Two layers show \\\" and the string is usually wrapped in quotes that are themselves escaped. Beyond that the backslashes outnumber the content and counting is quicker than reading.

A useful check is the start of the string. A correctly nested object begins with an unescaped brace; a doubly-encoded one begins with a quote followed by an escaped brace, which is a shape you learn to recognise instantly.

In a terminal, printf '%s\n' "$value" resolves one layer, and jq -r '.' resolves one more, so applying them in turn and watching the backslashes halve each time is the command-line equivalent of what the unstringify button does here.

Frequently asked questions

What does stringify actually do?
It validates and minifies your JSON, then wraps it in quotes and escapes every internal quote and control character, producing a string literal you can embed directly in source code.
When do I need an escaped JSON string?
Most often when embedding a JSON payload inside another JSON document, a shell command, an environment variable, or a test fixture, where the inner quotes would otherwise terminate the string early.
Why does unstringify say my input is not a quoted string?
Unstringify expects a string literal, meaning the whole input is wrapped in double quotes. If you paste a bare object, use stringify instead.
Is the payload I paste sent anywhere?
No. Escaping and unescaping happen in the page. This matters more here than on most tools, because the payloads people need to unescape are usually the ones pulled out of a production log while debugging.

Last updated:

Report a problem

Include the steps, expected result, and actual result. Remove secrets and personal data.

Related tools