Splitting the configuration file
If you configure Home Assistant using YAML, your configuration.yamlThe configuration.yaml file is the main configuration file for Home Assistant. It lists the integrations to be loaded and their specific configurations. In some cases, the configuration needs to be edited manually directly in the configuration.yaml file. Most integrations can be configured in the UI. [Learn more] file can grow large over time. You can split it into smaller, focused files using the !include directive.
Most Home Assistant features are configured through the UI and don’t require editing the configuration.yaml at all. This page is for you if you use YAML-based configuration and want to keep your files organized.
Example configuration files for inspiration
First off, several community members have sanitized (read: without API keys/passwords) versions of their configurations available for viewing. You can see a list of example configuration on GitHub.
As commenting code doesn’t always happen, please read on to learn in detail how configuration files can be structured.
How splitting works
The configuration.yaml file stays in place when you split it. You move parts of its content into separate files and reference them with !include.
A fresh configuration.yaml includes several entries that should not be removed:
# Loads a standard set of integrations. Keep this entry.
default_config:
# These files store automations, scripts, and scenes created in the UI.
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
If you have added customizations or packages, there may also be a homeassistant: key. Any !include statements under it, such as for customize: or packages:, should stay nested inside it.
The included file must contain valid YAML for the location where it is included. You do not repeat the parent key inside the included file.
For example, if configuration.yaml contains:
customize: !include customize.yaml
Then customize.yaml contains only the entries that belong under customize::
light.living_room:
friendly_name: "Living Room"
icon: mdi:ceiling-light
switch.patio:
friendly_name: "Patio Switch"
You can apply the same pattern to any integration:
switch: !include switch.yaml
sensor: !include sensor.yaml
Give files names that match their purpose, so they are easier to find and maintain.
Nesting !include statements also works. A file that is itself included can use !include to pull in further files.
Indentation
Home Assistant configuration files use YAML, where indentation is significant. Always use 2 spaces per level.
As a general rule:
- Top-level keys (like
homeassistant:,mqtt:, orsensor:) are fully left-aligned with no indent. - Keys nested under a parent are indented 2 spaces.
- List items (
-) are indented to the correct level, followed by a single space before the value.
# Top-level key: no indent
sensor:
# Nested key: 2 spaces
- platform: template
sensors:
living_room_temp:
friendly_name: "Living room temperature"
Incorrect indentation is one of the most common reasons a configuration file fails to load.
Comments
A # symbol marks a comment. Anything after it on that line is ignored by Home Assistant. Comments are useful for adding context or temporarily disabling a line without deleting it.
# Automations for public transport notifications
automation public transport: !include public-transport-automation.yaml
Multiple top-level keys
Some integrations support multiple top-level keys, letting you split their configuration across several files. Each key must have a different label. This applies to IoT domain integrations such as light, switch, and sensor, as well as automation, script, and template.
If an integration does not support multiple top-level keys, use Packages instead.
Example of multiple top-level keys
Here is an example using light. The first key keeps some entries inline, and the other keys use !include to pull in separate files:
configuration.yaml
light:
- platform: group
name: "Bedside Lights"
entities:
- light.left_bedside_light
- light.right_bedside_light
# More light groups in a separate file
light groups: !include light-groups.yaml
# Light switch mappings in a different file
light switches: !include light-switches.yaml
light-groups.yaml
- platform: group
name: "Outside Lights"
entities:
- light.porch_lights
- light.patio_lights
light-switches.yaml
- platform: switch
name: "Patio Lights"
entity_id: switch.patio_lights
- platform: switch
name: "Floor Lamp"
entity_id: switch.floor_lamp_plug
The same pattern works for automation:
# Automations managed in the UI
automation ui: !include automations.yaml
# Automations written by hand
automation manual: !include automations_manual.yaml
Using packages
Configuration can also be organized using Packages, which let you group all the configuration for a specific feature or room into a single file.
Debugging configuration files
If you have many configuration files, Home Assistant provides a CLI that allows you to see how it interprets them. Each installation type has its own section in the common-tasks about this:
Including entire directories
You can also include entire directories at once using four directory-level include options. The directory-level options only scan for files with the .yaml extension. Files with the .yml extension are ignored.
You can still use !include to load .yml files directly from within your .yaml files.
-
!include_dir_listreturns the content of a directory as a list with each file content being an entry in the list. The list entries are ordered based on the alphanumeric ordering of the names of the files. -
!include_dir_namedreturns the content of a directory as a dictionary that maps filenames to file contents. -
!include_dir_merge_listreturns the content of a directory as a list by merging all files (which should contain a list) into a single list. -
!include_dir_merge_namedreturns the content of a directory as a dictionary by loading each file and merging it into a single dictionary.
These work recursively. For example, !include_dir_list automation includes all 6 files shown below:
.
└── .homeassistant
├── automation
│ ├── lights
│ │ ├── turn_light_off_bedroom.yaml
│ │ ├── turn_light_off_lounge.yaml
│ │ ├── turn_light_on_bedroom.yaml
│ │ └── turn_light_on_lounge.yaml
│ ├── say_hello.yaml
│ └── sensors
│ └── react.yaml
└── configuration.yaml (not included)
Example: !include_dir_list
configuration.yaml
automation:
- alias: "Automation 1"
triggers:
- trigger: state
entity_id: device_tracker.iphone
to: "home"
actions:
- action: light.turn_on
target:
entity_id: light.entryway
- alias: "Automation 2"
triggers:
- trigger: state
entity_id: device_tracker.iphone
from: "home"
actions:
- action: light.turn_off
target:
entity_id: light.entryway
can be turned into:
configuration.yaml
automation: !include_dir_list automation/presence/
automation/presence/automation1.yaml
alias: "Automation 1"
triggers:
- trigger: state
entity_id: device_tracker.iphone
to: "home"
actions:
- action: light.turn_on
target:
entity_id: light.entryway
automation/presence/automation2.yaml
alias: "Automation 2"
triggers:
- trigger: state
entity_id: device_tracker.iphone
from: "home"
actions:
- action: light.turn_off
target:
entity_id: light.entryway
Each file must contain only one entry when using !include_dir_list.
Example: !include_dir_named
configuration.yaml
alexa:
intents:
LocateIntent:
actions:
action: notify.pushover
data:
message: "Your location has been queried via Alexa."
speech:
type: plaintext
text: >
{%- for state in states.device_tracker -%}
{%- if state.name.lower() == User.lower() -%}
{{ state.name }} is at {{ state.state }}
{%- endif -%}
{%- else -%}
I am sorry. Pootie! I do not know where {{User}} is.
{%- endfor -%}
WhereAreWeIntent:
speech:
type: plaintext
text: >
{%- if is_state('device_tracker.iphone', 'home') -%}
iPhone is home.
{%- else -%}
iPhone is not home.
{% endif %}
can be turned into:
configuration.yaml
alexa:
intents: !include_dir_named alexa/
alexa/LocateIntent.yaml
actions:
action: notify.pushover
data:
message: "Your location has been queried via Alexa."
speech:
type: plaintext
text: >
{%- for state in states.device_tracker -%}
{%- if state.name.lower() == User.lower() -%}
{{ state.name }} is at {{ state.state }}
{%- endif -%}
{%- else -%}
I am sorry. Pootie! I do not know where {{User}} is.
{%- endfor -%}
alexa/WhereAreWeIntent.yaml
speech:
type: plaintext
text: >
{%- if is_state('device_tracker.iphone', 'home') -%}
iPhone is home.
{%- else -%}
iPhone is not home.
{% endif %}
Example: !include_dir_merge_list
configuration.yaml
automation:
- alias: "Automation 1"
triggers:
- trigger: state
entity_id: device_tracker.iphone
to: "home"
actions:
- action: light.turn_on
target:
entity_id: light.entryway
- alias: "Automation 2"
triggers:
- trigger: state
entity_id: device_tracker.iphone
from: "home"
actions:
- action: light.turn_off
target:
entity_id: light.entryway
can be turned into:
configuration.yaml
automation: !include_dir_merge_list automation/
automation/presence.yaml
- alias: "Automation 1"
triggers:
- trigger: state
entity_id: device_tracker.iphone
to: "home"
actions:
- action: light.turn_on
target:
entity_id: light.entryway
- alias: "Automation 2"
triggers:
- trigger: state
entity_id: device_tracker.iphone
from: "home"
actions:
- action: light.turn_off
target:
entity_id: light.entryway
When using !include_dir_merge_list, you must include a list in each file (each list item is denoted with a hyphen (-)). Each file may contain one or more entries.
Example: !include_dir_merge_named
configuration.yaml
group:
bedroom:
name: "Bedroom"
entities:
- light.bedroom_lamp
- light.bedroom_overhead
hallway:
name: "Hallway"
entities:
- light.hallway
- thermostat.home
front_yard:
name: "Front Yard"
entities:
- light.front_porch
- light.security
- light.pathway
- sensor.mailbox
- camera.front_porch
can be turned into:
configuration.yaml
group: !include_dir_merge_named group/
group/interior.yaml
bedroom:
name: "Bedroom"
entities:
- light.bedroom_lamp
- light.bedroom_overhead
hallway:
name: "Hallway"
entities:
- light.hallway
- thermostat.home
group/exterior.yaml
front_yard:
name: "Front Yard"
entities:
- light.front_porch
- light.security
- light.pathway
- sensor.mailbox
- camera.front_porch
Example: Combine !include_dir_merge_list with automations.yaml
Do you want to split your automations, while still being able to create them in Settings > Automations & scenes? Here is how you can do that for automations.
Using labels like manual or ui allows for using multiple keys in the config:
configuration.yaml
# My own handmade automations
automation manual: !include_dir_merge_list automations/
# Automations I create in the UI
automation ui: !include automations.yaml
Example configuration files for inspiration
Several community members have shared versions of their configurations without sensitive information, like API keys and passwords. You can see a list of example configurations on GitHub.