X Xerobit

YAML Multiline Strings — Literal Block and Folded Scalars

YAML has two multiline string styles: literal block (|) preserves newlines, folded (>) folds newlines into spaces. Here's how to write multiline strings in YAML, control...

Mian Ali Khalid · · 4 min read
Use the tool
YAML ↔ JSON Converter
Convert between YAML and JSON formats with full fidelity.
Open YAML ↔ JSON Converter →

YAML provides two styles for multiline strings: the literal block scalar (|) preserves newlines exactly, and the folded scalar (>) folds newlines into spaces. Getting these right matters for shell scripts, SQL queries, and long descriptions in config files.

Use the YAML to JSON Converter to test how YAML parses multiline strings.

Literal block scalar: |

The | indicator preserves all newlines:

message: |
  Hello, World!
  This is a second line.
  And a third.

Parsed as:

"Hello, World!\nThis is a second line.\nAnd a third.\n"

The leading indentation (2 spaces here) is stripped. Content indented further than the first line is preserved as extra indentation.

Use | for:

# Shell scripts:
script: |
  #!/bin/bash
  set -e
  npm install
  npm run build
  npm run test

# SQL queries:
query: |
  SELECT u.id, u.name, COUNT(o.id) as order_count
  FROM users u
  LEFT JOIN orders o ON o.user_id = u.id
  WHERE u.active = true
  GROUP BY u.id, u.name
  ORDER BY order_count DESC

# Poetry/text preserving line breaks:
poem: |
  Roses are red,
  Violets are blue,
  YAML is powerful,
  And so are you.

Folded scalar: >

The > indicator replaces single newlines with spaces — useful for long sentences you want to wrap in the source:

description: >
  This is a very long description that wraps
  across multiple lines in the source file
  but will be joined into a single paragraph
  with spaces between the wrapped lines.

Parsed as:

"This is a very long description that wraps across multiple lines in the source file but will be joined into a single paragraph with spaces between the wrapped lines.\n"

Blank lines create real newlines (paragraph breaks):

description: >
  First paragraph content
  that spans two lines.

  Second paragraph — the blank
  line above creates a newline.

Parsed as:

"First paragraph content that spans two lines.\nSecond paragraph — the blank line above creates a newline.\n"

Chomping indicators

By default, both | and > keep exactly one trailing newline. You can change this:

IndicatorBehaviorExample
`or>`Keep one trailing newline (default)
`-or>-`Strip all trailing newlines (chomp)
`+or>+`Keep all trailing newlines
# Clip (default): exactly one trailing newline
clip: |
  line one
  line two

# Strip: no trailing newline
strip: |-
  line one
  line two

# Keep: preserve all trailing newlines
keep: |+
  line one
  line two

In JSON output:

{
  "clip": "line one\nline two\n",
  "strip": "line one\nline two",
  "keep": "line one\nline two\n\n\n"
}

Indentation indicator

When content starts with a space, you need an explicit indent level:

# Content starts with a space — need indent indicator (2):
indented: |2
    This content has 2 extra spaces at the start.
    The "2" tells YAML the base indentation level.

Without the 2, YAML would use the first line’s indentation as the base, which could be wrong.

Docker Compose / GitHub Actions examples

# Docker Compose multi-line command:
services:
  web:
    command: |
      sh -c "
        npm install &&
        npm run migrate &&
        npm start
      "

# GitHub Actions run step:
jobs:
  build:
    steps:
      - name: Build and test
        run: |
          npm ci
          npm run lint
          npm run test
          npm run build

      - name: Deploy
        run: >
          aws s3 sync ./dist s3://my-bucket
          --delete
          --cache-control max-age=31536000
          --exclude "*.html"

Note the > in the deploy step folds the command onto one line (useful for long aws commands).

Kubernetes multiline

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  # Literal: preserves exact formatting
  nginx.conf: |
    server {
      listen 80;
      location / {
        proxy_pass http://backend;
      }
    }
  
  # Folded: join wrapped description
  description: >
    This application provides REST API endpoints
    for user management and authentication
    using JWT tokens.

Flow vs block scalars

YAML also has flow scalars (quoted strings) for multiline content:

# Single-quoted: literal \n, preserves most characters
single: 'First line
  Second line'  # Becomes "First line Second line" (folded)

# Double-quoted: interprets \n, \t, etc.
double: "First line\nSecond line"  # Real newline

# Block scalars (| and >) are better for readability
block: |
  First line
  Second line

Common mistakes

# WRONG: unquoted string with colon looks like a key
message: Hello: World  # Parsing error

# CORRECT: use block scalar or quotes
message: |
  Hello: World
message: "Hello: World"

# WRONG: mixing indentation in block scalar
script: |
  first line
    second line  # This is intentional extra indentation
  back to base   # OK — relative indentation

Related posts

Related tool

YAML ↔ JSON Converter

Convert between YAML and JSON formats with full fidelity.

Written by Mian Ali Khalid. Part of the Data & Format pillar.