Skip to content

YAML to JSON Block Scalar Trailing Newline: Why \n Appears

admin10 min read
Illustration of a YAML to JSON block scalar trailing newline shown as a line break turning into an escape symbol

A YAML literal block written with | keeps its final line break, so after conversion the JSON string ends in \n. That is the YAML to JSON block scalar trailing newline: a real line feed character in the parsed value, which JSON can only display as an escape sequence. Use |- when you want no final newline, bare | for exactly one, and |+ when trailing blank lines must survive.

This guide takes YAML text as input and produces JSON string values as output. I use a three-key comparison you can paste into the YAML to JSON converter, then show how to check the decoded string instead of judging by how the escape looks.

Conceptual illustration of a text line ending in a return arrow, representing a trailing newline in converted data

YAML to JSON Block Scalar Trailing Newline: The Short Answer

The trailing \n is not added by the converter. In YAML 1.2.2, a literal block scalar introduced by | uses the default chomping behavior called clip: the content keeps its final line break and any trailing empty lines are discarded. The parsed string therefore really does end with a line feed character. The YAML 1.2.2 specification describes this in section 8.1.1.2 and in its block scalar examples.

JSON then has to write that character down. RFC 8259 does not allow an unescaped line feed inside a quoted string, so the character appears as the two-character escape \n. When a program reads the JSON, the escape decodes back into one line feed.

The site’s YAML to JSON page says it parses YAML with js-yaml 4.1.0 and writes the resulting JavaScript values with JSON.stringify, as documented on October 5, 2026. That pipeline matches what you see: the YAML parser decides the string value, and JSON.stringify chooses the notation. Keep those two layers apart and most of the confusion disappears. The value is what your program receives, and the notation is how the text file spells it.

The sections below show the three chomping indicators side by side, explain the escape, and finish with a check that tests the decoded string.

Compare |, |- and |+ in One YAML Document

Paste this YAML into the converter exactly as printed. It has 7 lines and no empty lines, so it shows the baseline first. A second step then adds the one empty line that makes |+ differ from |. Indent the block content with two spaces.

strip: |-
  hello
clip: |
  hello
keep: |+
  hello
after: true

For this exact input, the expected JSON string values follow from the specification:

{
  "strip": "hello",
  "clip": "hello\n",
  "keep": "hello\n",
  "after": true
}

Because no empty line follows any hello, clip and keep match. Now add one empty line in your editor directly after the hello under keep, before after: true, with nothing typed on it. The input becomes 8 lines, and only keep changes.

HeaderYAML nameFinal line breakTrailing empty linesPrinted sampleWith empty line added
|-stripDiscardedDiscarded"hello""hello"
|clipOne keptDiscarded"hello\n""hello\n"
|+keepKeptKept"hello\n""hello\n\n"

An empty line after the content under strip or clip is dropped by those indicators, so their values do not change. Under keep, that empty line is retained and contributes a second line feed, and the after key marks where the block ends.

Do not read this as “|+ always adds a newline”. Without a trailing empty line, | and |+ both produce "hello\n". I describe the empty line as a manual step on purpose: blank lines are easy to lose when code is copied from a web page, and a lost blank line silently changes the keep result.

Conceptual illustration of one hidden line break shown as a different symbol in JSON notation

Why JSON Shows \n Instead of a Real Line Break

Three different things can look alike when you read converted output, so name them separately.

  • The decoded value: one line feed character at the end of the string.
  • The JSON notation: the two characters backslash and n inside the quotes, which a JSON parser decodes into that line feed.
  • A literal backslash followed by n: a different string value, spelled with two backslashes in JSON.

A short YAML document shows the difference. Single-quoted YAML does not process escapes, double-quoted YAML does, and the block scalar produces a real line feed:

single: 'hello\n'
double: "hello\n"
block: |
  hello

The JSON output is:

{
  "single": "hello\\n",
  "double": "hello\n",
  "block": "hello\n"
}

The single value contains a backslash and the letter n, so JSON spells the backslash as \\ and the output shows \\n. The double and block values contain a line feed, so JSON shows \n. When you scan converted output, a single backslash before n means a line feed, and a doubled backslash means literal characters.

Also separate the string from the file around it. JSON allows insignificant whitespace outside values, so a newline after the closing brace of the output is not inside any string and has nothing to do with block chomping.

Control the YAML to JSON block scalar trailing newline on purpose

Decide what the consumer of the string expects, then pick the indicator that produces it. Do not fix the symptom later by trimming the JSON text, because the JSON text is only a spelling of the value.

  • Use |- (strip) when the string should not end with a line break, such as a sentence, a short label or a value you will compare with an exact string.
  • Use | (clip) when one final line feed is right, which suits text content where a closing newline is conventional.
  • Use |+ (keep) only when trailing blank lines are part of the data. If no empty line follows the content, |+ gives the same single final line feed as |.

It matters because equality comparisons and hashes treat a string with and without a final line feed as different values.

These indicators govern only the end of the string. Interior line breaks in a literal block stay line breaks whichever indicator you choose:

note: |-
  line one
  line two

The JSON string for that note is "line one\nline two", with an escaped line feed between the lines and none at the end. Change the header to | and a final \n appears.

A related article explains why YAML anchors and merge keys disappear when you convert to JSON. The idea is the same: JSON keeps the resolved data, not the YAML notation that produced it.

Steps in the Converter and How to Verify the Result

Follow these steps to run the comparison and test the result.

  1. Paste the 7-line YAML from the comparison section into the YAML to JSON page, keeping the two-space indentation of each hello line.
  2. Pick the output indentation the page offers.
  3. Read the JSON output. strip should be hello, clip should end with hello\n, and keep should also end with hello\n, because no empty line follows it yet.
  4. Add one empty line directly after the hello under keep, before after: true, and convert again. Now keep should end with hello\n\n, while strip and clip stay the same. If keep still shows one \n, the empty line was not added, so insert it and convert once more.
  5. Copy or download the JSON.

If the input is rejected or the output looks wrong, run the text through the YAML Validator first. It displays error messages for invalid syntax, which catches broken indentation, but it cannot tell you whether a trailing newline is what your application wants.

To test the decoded strings instead of the escapes, open the JavaScript Editor, paste the snippet below and run it. The editor runs code in the browser and shows synchronous console output, so run only code you wrote or trust.

const first = JSON.parse(String.raw`{"strip":"hello","clip":"hello\n","keep":"hello\n"}`);
const second = JSON.parse(String.raw`{"keep":"hello\n\n"}`);
console.log(first.strip === "hello");
console.log(first.clip === "hello\n");
console.log(first.keep === "hello\n");
console.log(second.keep === "hello\n\n");

Each line should log true. The first object matches the printed sample and the second matches the keep value after you add the empty line. String.raw keeps the backslash and n as typed, so JSON.parse does the decoding, exactly as your application would.

For a reverse look, the JSON to YAML converter accepts valid JSON and writes YAML with proper string quoting. I have not verified which scalar style it picks for strings that contain line breaks, so treat that result as a value check, not a style guarantee.

Limits and Edge Cases to Test Yourself

These outputs follow the YAML 1.2.2 specification and the converter’s published processing description. I have not recorded a hands-on run of the live page for this article, and the site’s description of js-yaml 4.1.0 and JSON.stringify was read on October 5, 2026. If the exact behavior matters, confirm it with your own sample.

  • The examples assume the line breaks and blank lines really exist in your input. A paste that drops blank lines or alters line endings can change the keep result.
  • A block scalar at the very end of a file with no final line break, or an empty block, needs separate testing. I make no claim about those cases.
  • Indentation is content. Leading spaces beyond the block’s own indentation stay in the string.
  • Syntax checks are not meaning checks. The YAML Validator reports YAML syntax and the JSON Validator checks JSON syntax with JSON.parse, so neither can judge whether a string should end in a line feed.
  • Reformatting can change style. A YAML Formatter reparses and serializes the document, which can remove comments or change scalar styles, so retest block scalars after formatting.
  • A newline after the JSON output is outside every string and is unrelated to |, |- or |+.

For wider background on keeping YAML clean, see the YAML formatter and validator guide.

Frequently asked questions

Why does my YAML block string end with \n after conversion?

A literal block written with a bare | keeps its final line break, so the parsed string ends in a line feed. JSON cannot hold an unescaped line feed inside a quoted string, so it shows that character as \n.

What is the difference between |, |- and |+?

Bare | is clip: it keeps one final line break and discards trailing empty lines. |- is strip: it discards the final break and trailing empty lines. |+ is keep: it retains the final break and any trailing empty lines.

Is the \n an extra newline added by the converter?

No. The YAML parser decides that the value ends with a line feed, and JSON.stringify only spells it as an escape. Changing the block header to |- removes the line feed from the value itself.

How do I remove the trailing newline from the JSON string?

Change the YAML header from | to |- and convert again. That is more reliable than editing the JSON text by hand, because the source then describes the value you actually want.

Does |+ always add an extra newline?

No. It keeps trailing empty lines if they exist. Without an empty line after the content, |+ and | both produce a single final \n. In the comparison above, the blank line before after is what creates the second line feed.

How can I tell a real line feed from a literal backslash and n?

Look at the raw JSON. A single backslash before n means one line feed. A doubled backslash before n means the string contains a backslash and the letter n, as in a single-quoted YAML scalar like ‘hello\n’.

Do the validators prove the trailing newline is correct?

No. A YAML validator checks YAML syntax and a JSON validator checks JSON syntax. Neither knows whether your application wants a final line feed. Parse the JSON and compare the string with the exact value you expect, such as “hello\n”.

Next steps

The YAML to JSON block scalar trailing newline is a difference of notation, not an error. A bare | keeps one final line feed in the value, and JSON writes it as \n. Choose |- for none, | for one and |+ for preserved trailing blank lines. As a next step, paste the three-key sample into the converter, parse the output, and confirm each string against the values listed above before you rely on it in your own data.

Related tools and resources on HTML Editor Online:

Sources and further reading

Try it in your browser

Free online editors with syntax highlighting. Open one and start coding, no account needed.

All Tools