YAML is popular because it lets people describe configuration in a way that feels close to plain English while still being precise enough for software. One of its most useful patterns is the array of objects: a list where each item contains several named properties. You will see this structure everywhere, from Docker Compose files and CI pipelines to application settings, Kubernetes manifests, and static site generators.
TLDR: A YAML array of objects is a list of structured items, where each item is usually introduced with a hyphen and contains key value pairs. It is ideal for describing repeatable configuration, such as users, services, jobs, routes, or environments. The most important rules are consistent indentation, clear object boundaries, and predictable property names. Once you understand this pattern, many real world configuration files become much easier to read and edit.
What Is a YAML Array of Objects?
In YAML, an array is a list. An object, often called a mapping, is a collection of keys and values. Put them together, and you get a list of structured entries.
Here is a simple example:
users:
- name: Alice
role: admin
active: true
- name: Ben
role: editor
active: false
- name: Clara
role: viewer
active: true
The key users contains an array. Each item in the array starts with a hyphen, and each item is an object with three properties: name, role, and active. This is compact, readable, and easy to expand.
Why Arrays of Objects Are So Common
Configuration often means describing several similar things. You might need multiple containers, several deployment environments, a group of navigation links, or a set of scheduled jobs. Instead of creating separate keys like user1, user2, and user3, YAML lets you express those related entries as a clean list.
- Readable: Each item appears as a self contained block.
- Scalable: You can add or remove items without restructuring the whole file.
- Consistent: Repeated objects encourage shared property names.
- Tool friendly: Applications can easily loop through the array and process each object.
Example 1: Application Environments
A common use case is defining multiple environments for an application. Each environment may have a name, URL, logging level, and feature flags.
environments:
- name: development
url: http://localhost:3000
logLevel: debug
features:
payments: false
emailNotifications: false
- name: staging
url: https://staging.example.com
logLevel: info
features:
payments: true
emailNotifications: true
- name: production
url: https://example.com
logLevel: warn
features:
payments: true
emailNotifications: true
Notice that objects can contain nested objects too. The features key is not an array; it is a nested mapping. YAML structures can be combined naturally, which makes it useful for configuration that has several layers.
Example 2: Service Configuration
Arrays of objects are especially helpful when configuring multiple services. This style is common in deployment tools, local development setups, and infrastructure files.
services:
- name: api
image: company/api:latest
port: 8080
replicas: 3
environment:
NODE_ENV: production
CACHE_ENABLED: true
- name: worker
image: company/worker:latest
replicas: 2
environment:
QUEUE_NAME: jobs
RETRY_LIMIT: 5
- name: dashboard
image: company/dashboard:latest
port: 3000
replicas: 1
Each service has its own settings, but not every object needs exactly the same keys. For example, worker does not have a port, because it may not expose an HTTP interface. This flexibility is convenient, but it should be used carefully. If your application expects every service to have a certain field, leaving it out may cause validation errors.
Indentation Is Everything
YAML does not use braces to define structure. It uses indentation. That is elegant, but it also means small spacing mistakes can change the meaning of your file or break it completely.
Compare this correct version:
jobs:
- name: build
steps:
- install dependencies
- run tests
- compile assets
With this incorrect version:
jobs:
- name: build
steps:
- install dependencies
- run tests
- compile assets
In the incorrect version, steps is no longer clearly part of the build job. Many parsers will treat it as a separate key under jobs or reject the file, depending on context. The safest habit is to use spaces consistently, usually two spaces per indentation level, and avoid tabs entirely.
Inline Versus Block Style
YAML also supports an inline style that looks more like JSON:
users: [{name: Alice, role: admin}, {name: Ben, role: editor}]
This is valid, but it becomes hard to read as objects grow. For configuration files, block style is usually preferred:
users:
- name: Alice
role: admin
- name: Ben
role: editor
Inline style can be useful for tiny examples or short values, but block style is better for maintainability, version control diffs, and team collaboration.
Example 3: CI Pipeline Jobs
Another practical example is a continuous integration pipeline. A pipeline typically contains multiple jobs, and each job contains its own commands, dependencies, and conditions.
pipeline:
- name: lint
image: node:20
commands:
- npm ci
- npm run lint
- name: test
image: node:20
commands:
- npm ci
- npm test
dependsOn:
- lint
- name: deploy
image: alpine:latest
commands:
- ./deploy.sh
dependsOn:
- test
only:
branch: main
This example shows arrays inside arrays of objects. The top level pipeline key holds a list of job objects. Each job has a commands array, and some jobs have a dependsOn array. This nested structure maps nicely to how pipelines actually work.
Common Mistakes to Avoid
- Mixing tabs and spaces: YAML parsers generally dislike tabs for indentation.
- Inconsistent object shapes: If some objects use
titleand others usename, your configuration becomes harder to process. - Forgetting the hyphen: Without the hyphen, you are creating a mapping, not a list item.
- Over nesting: Deeply nested YAML can become difficult to understand. Split complex configuration when possible.
- Unquoted special values: Strings like
yes,no, or version numbers may be interpreted unexpectedly by some parsers. Quote values when in doubt.
Best Practices for Clear YAML Arrays
Use meaningful names, keep indentation consistent, and group related fields in the same order for every object. If you are defining services, for example, put name, image, port, and environment in a predictable sequence. This makes scanning the file much easier.
It is also wise to validate YAML files before deploying them. Many bugs in configuration are not logical errors but formatting errors: one misplaced space, one missing hyphen, or one value at the wrong level. A YAML linter or schema validator can catch these problems early.
Final Thoughts
YAML arrays of objects are simple in concept but powerful in practice. They let you describe repeated, structured configuration in a way that both humans and machines can understand. Whether you are defining users, environments, services, routes, or build jobs, the same pattern applies: start each item with a hyphen, indent its properties consistently, and keep the structure predictable. Master this pattern, and a large portion of modern configuration files will become far less mysterious.
