Skip to content

YAML – Flow Styles

YAML’s flow styles provide a compact, often single-line, way to represent collections (sequences and mappings) and scalars. They are syntactically similar to JSON and are particularly useful for simple data structures or when embedding data within larger block-style structures. This chapter explores common flow style constructs.

Flow styles are characterized by explicit delimiters: [] for sequences and {} for mappings.

Flow sequences are enclosed in square brackets [], with items separated by commas (and optionally a space). Example:

colors: [red, green, blue]
empty_list: []
mixed_types: [1, "apple", true, {type: "fruit"}]

The JSON equivalent for colors would be: {"colors": ["red", "green", "blue"]}

2. Flow Mappings (Inline Dictionaries/Objects)

Section titled “2. Flow Mappings (Inline Dictionaries/Objects)”

Flow mappings are enclosed in curly braces {}, with key-value pairs separated by commas. Keys and values are separated by a colon and a space. Example:

user: {name: "Alice", age: 28, city: "London"}
empty_object: {}
config: {enabled: true, port: 8080}

The JSON equivalent for user would be: {"user": {"name": "Alice", "age": 28, "city": "London"}}

While scalars themselves don’t have distinct “flow” delimiters like collections, they are the content within flow collections. Flow scalars can be plain (unquoted), single-quoted, or double-quoted.

# Scalars within a flow sequence
items: [plain_scalar, 'single quoted', "double quoted with \"escapes\""]
# Scalars within a flow mapping
details: {id: 123, notes: 'A simple note.', message: "Status: OK"}

Empty values or nulls can be represented in flow style using null or ~, or by having an empty scalar value (e.g., for strings).

data: { key1: null, key2: ~, key3: '', key4: }

JSON output for the above:

{
"data": {
"key1": null,
"key2": null,
"key3": "",
"key4": null
}
}

Anchors (&) and aliases (*) work seamlessly with flow styles, allowing for data reuse.

# YAML 1.2
default_config: &defaults { timeout: 5000, retries: 3 }
service1_config: { <<: *defaults, port: 8081 } # Merge with defaults
service2_config: { <<: *defaults, port: 8082, timeout: 10000 } # Override timeout
user_list:
- &user1 { name: "Bob" }
- { name: "Charlie" }
admin_users: [*user1]

The JSON output (after resolving anchors/aliases and merges):

{
"default_config": { "timeout": 5000, "retries": 3 },
"service1_config": { "timeout": 5000, "retries": 3, "port": 8081 },
"service2_config": { "timeout": 10000, "retries": 3, "port": 8082 },
"user_list": [
{ "name": "Bob" },
{ "name": "Charlie" }
],
"admin_users": [
{ "name": "Bob" }
]
}

Flow collections can be nested within each other, or within block collections.

matrix: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
complex_object:
id: "obj123"
properties: {color: "blue", size: "large"}
tags: ["tagA", "tagB"]
# Flow mapping with a flow sequence value
coordinates: { x_values: [10, 20, 30], y_values: [15, 25, 35] }

JSON output for matrix:

{
"matrix": [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
}
  • For simple, compact data structures where inline representation is clear.
  • When data closely resembles JSON objects or arrays.
  • Embedding small collections within block structures (e.g., a list of tags for a blog post).
  • When generating YAML that needs to be easily parsable by simpler JSON tools (though direct JSON output is usually better for this).

Caution: Overuse of deeply nested flow styles for complex data can significantly reduce readability compared to their block style counterparts. A balance is often best, choosing the style that best fits the data’s complexity and the need for clarity.