Indenting YAML files

YAML files are omnipresent: whether you use continuous integration systems, external code quality tools, or container virtualization, the chances are that you are dealing with YAML files.

At first glance, the YAML specification is straightforward:

Whitespace is essential - but how much?

I recommend using two spaces of indentation for YAML files. But let's take a closer look!

Sequences

A flow sequence contains values separated by commas and surrounded by square brackets.

The example below shows a flow sequence.

["8.0", "8.1", "8.2"]

A block sequence is a series of nodes, each denoted by a leading dash.

The example below shows a block sequence.

- "8.0"
- "8.1"
- "8.2"

According to the YAML specification, the examples above are equivalent.

Mappings

A flow mapping contains values separated by commas and surrounded by curly braces.

The example below shows a flow mapping.

{ name: "bug", color: "ee0701" }

A block mapping is a series of entries, each representing pairs of keys and values.

The example below shows a block mapping.

name: "bug"
color: "ee0701"

According to the YAML specification, the examples above are equivalent.

Indentation spaces

Indentation spaces are zero or more space characters at the beginning of a line.

Following a key and a colon, you start a new block mapping by indenting a line of YAML with more spaces than the previous line. By indenting a line of YAML with fewer spaces than the previous line, you close a block mapping.

According to the YAML specification, the amount of indentation is an implementation detail.

The example below shows a combination of sequences and mappings using two spaces of indentation. Note how the sequence assigned to the mapping is indented.

labels:
  - name: "bug"
    color: "ee0701"

  - name: "enhancement"
    color: "0e8a16"

repository:
  allow_merge_commit: true
  allow_rebase_merge: false
  default_branch: "main"

The example below shows a combination of sequences and mappings using two spaces of indentation. Note how the sequence assigned to the mapping does not use indentation.

labels:
- name: "bug"
  color: "ee0701"

- name: "enhancement"
  color: "0e8a16"

repository:
  allow_merge_commit: true
  allow_rebase_merge: false
  default_branch: "main"

The example below shows a combination of sequences and mappings using four (and two) spaces of indentation. Note how the sequence assigned to the mapping inconsistently uses two spaces of indentation.

labels:
    - name: "bug"
      color: "ee0701"

    - name: "enhancement"
      color: "0e8a16"

repository:
    allow_merge_commit: true
    allow_rebase_merge: false
    default_branch: "main"

The example below shows a combination of sequences and mappings using four spaces of indentation. Note how the sequence assigned to the mapping consistently uses four spaces of indentation.

labels:
    -   name: "bug"
        color: "ee0701"

    -   name: "enhancement"
        color: "0e8a16"

repository:
    allow_merge_commit: true
    allow_rebase_merge: false

The example below shows a combination of sequences and mappings using four spaces of indentation. Note how the sequence assigned to the mapping consistently uses four spaces of indentation and how the mappings in the sequence wrap to ensure consistent indentation.

labels:
    -
        name: "bug"
        color: "ee0701"

    -
        name: "enhancement"
        color: "0e8a16"

repository:
    allow_merge_commit: true
    allow_rebase_merge: false

According to the YAML specification, the above examples are equivalent.

Separation spaces

Separation spaces are sequences of space or tab characters outside of indentation and string literals for separating tokens within a single line. For example, you use spaces and tabs to separate a colon and a value when creating mappings or a dash from a value when creating block sequences.

The example below uses a single space to separate colons and dashes from values.

labels:
  - name: "bug"
    color: "ee0701"

  - name: "enhancement"
    color: "0e8a16"

repository:
  allow_merge_commit: true
  allow_rebase_merge: false
  default_branch: "main"

The example below uses varying numbers of spaces before and a single space after colons to separate colons from values.

labels:
  - name : "bug"
    color: "ee0701"

  - name : "enhancement"
    color: "0e8a16"

repository:
  allow_merge_commit: true
  allow_rebase_merge: false
  default_branch    : "main"

The example below uses varying numbers of spaces after colons to separate colons from values.

labels:
  - name:  "bug"
    color: "ee0701"

  - name:  "enhancement"
    color: "0e8a16"

repository:
  allow_merge_commit: true
  allow_rebase_merge: false
  default_branch:     "main"

According to the YAML specification, the above examples are equivalent.

Indentation in YAML in the real world

So how do people use indentation spaces in the real world?

Indentation of block sequences and mappings with two spaces

The following indent block sequences and mappings with two spaces:

Indentation of block mappings with two spaces

The following indent block mappings with two spaces but do not indent block sequences:

Indentation of block sequences and mappings with four spaces

The following indent block sequences and mappings with four spaces:

Indentation of block mappings with four spaces

The following indent block mappings with four spaces, but do not indent block sequences:

Recommendation

Avoid YAML

Avoid YAML when possible.

For example, it is not necessary to configure a Symfony application with YAML files. Symfony not only supports YAML, but also XML (cough), and PHP configuration file formats. You can easily convert Symfony YAML (and XML) configuration files to PHP files with symplify/config-transformer.

Use two spaces of indentation

Do yourself a favor, and indent YAML files with two instead of four spaces. When you use two spaces of indentation for block sequences and mappings, you can avoid inconsistent indentation and awkward wrapping.

As you can see from the collection above, most services that use YAML files implicitly suggest to use two spaces of indentation.

Use EditorConfig

Use EditorConfig to configure indentation size and indentation type for YAML files in every project that uses YAML files. Most IDEs have built-in support for EditorConfig and will adjust their code style configuration.

Here is an example of an .editorconfig that configures an indentation of two spaces for YAML files:

[*.{yaml,yml}]
indent_size = 2
indent_style = space

Use Yamllint

Use Yamllint to lint YAML files in local development environments and continuous integration systems.

Here is an example of a .yamllint.yaml that configures an indentation of two spaces and a separation of one space.

extends: "default"

ignore: |
  .build/
  vendor/

rules:
  braces:
    max-spaces-inside-empty: 0
    max-spaces-inside: 1
    min-spaces-inside-empty: 0
    min-spaces-inside: 1
  brackets:
    max-spaces-inside-empty: 0
    max-spaces-inside: 0
    min-spaces-inside-empty: 0
    min-spaces-inside: 0
  colons:
    max-spaces-after: 1
    max-spaces-before: 0
  commas:
    max-spaces-after: 1
    max-spaces-before: 0
    min-spaces-after: 1
  comments:
    ignore-shebangs: true
    min-spaces-from-content: 1
    require-starting-space: true
  comments-indentation: "enable"
  document-end:
    present: false
  document-start:
    present: false
  indentation:
    check-multi-line-strings: false
    indent-sequences: true
    spaces: 2
  empty-lines:
    max-end: 0
    max-start: 0
    max: 1
  empty-values:
    forbid-in-block-mappings: true
    forbid-in-flow-mappings: true
  hyphens:
    max-spaces-after: 2
  key-duplicates: "enable"
  key-ordering: "disable"
  line-length: "disable"
  new-line-at-end-of-file: "enable"
  new-lines:
    type: "unix"
  octal-values:
    forbid-implicit-octal: true
  quoted-strings:
    quote-type: "double"
  trailing-spaces: "enable"
  truthy: "enable"

yaml-files:
  - "*.yaml"
  - "*.yml"

Do you find this article helpful?

Do you have feedback?

Do you need help with your PHP project?