Skill detail
home-assistant-best-practices
Best practices for HA automations, helpers, scripts, and dashboards. TRIGGER THIS SKILL WHEN: - Creating or editing automations, scripts, scenes, dashboards, blueprints - Choosing template sensors, helpers, or Jinja macros - Restructuring triggers, conditions, or modes; button, remote, or…
Why we recommend it: Best practices for Home Assistant automations, helpers, scripts, and dashboards, covering native triggers/conditions, helper selection, safe refactoring, and Jinja2 template avoidance.
Inspect before use
Read the source instructions and check the requirements before you install this skill.
SKILL.md
The saved excerpt is a snapshot from when this skill was listed. The external source remains the complete and most current version.
---
name: home-assistant-best-practices
description: >
Best practices for HA automations, helpers, scripts, and dashboards.
TRIGGER THIS SKILL WHEN:
- Creating or editing automations, scripts, scenes, dashboards, blueprints
- Choosing template sensors, helpers, or Jinja macros
- Restructuring triggers, conditions, or modes; button, remote, or event-entity automations
- Renaming entities or migrating device_id to entity_id
- Looking up card types or domain docs; writing AppDaemon apps
- Deleting or restoring a backup, or upgrading Core or the OS
SYMPTOMS:
- Jinja2 templates where native options exist
- device_id used instead of entity_id
- Entity IDs changed without checking consumers
- Wrong automation mode chosen
- Raw sensor or hard-coded value used where a helper belongs
- Direct .storage edits, or generated YAML snippets
- User told to edit configuration.yaml for UI integrations
- Hardcoded Blueprint entities or skipped selectors
- Existing state changed with no recovery path
- Jinja copy-pasted between templates
metadata:
version: "34"
---
# Home Assistant Best Practices
**Core principle:** Use native Home Assistant constructs wherever possible. Templates bypass validation, fail silently at runtime, and make debugging opaque.
## Decision Workflow
Follow this sequence when creating any automation:
### 0. Gate: modifying existing config?
If your change affects entity IDs, display names, or cross-component references — renaming entities or devices, replacing template sensors with helpers, converting device triggers, or restructuring automations — read [safe-refactoring](references/safe-refactoring.md) first. That reference covers impact analysis, device-sibling discovery, display-name overrides, and post-change verification. Complete its workflow before proceeding.
Steps 1-5 below apply to new config or pattern evaluation.
### 1. Check for a purpose-specific, then generic native, trigger/condition
Since 2026.7 the default building blocks are purpose-specific triggers/conditions — `<domain>.<name>` keys (motion detected, battery low, door opened) with area/floor/label targets. Check for one that matches the intent first, then a generic native trigger/condition, and only then a template. See [automation-patterns #purpose-specific-triggers--conditions-default-since-20267](references/automation-patterns.md#purpose-specific-triggers--conditions-default-since-20267).
**Common substitutions:**
- List of individual sensor entities in a trigger → one purpose-specific trigger with an area/floor/label `target:`
- `{{ states('x') | float > 25 }}` → `numeric_state` condition with `above: 25`
- `{{ is_state('x', 'on') and is_state('y', 'on') }}` → `condition: and` with state conditions
- `{{ now().hour >= 9 }}` → `condition: time` with `after: "09:00:00"`
- `wait_template: "{{ is_state(...) }}"` → `wait_for_trigger` with state trigger (caveat: different behavior when state is already true — see [safe-refactoring #trigger-restructuring](references/safe-refactoring.md#trigger-restructuring))
### 2. Check for built-in helper or Template Helper
Before creating a template sensor, check [helper-selection](references/helper-selection.md).
**Common substitutions:**
- Sum/average multiple sensors → `min_max` integration
- Binary any-on/all-on logic → `group` helper
- Rate of change → `derivative` integration
- Cross threshold detection → `threshold` integration
- Consumption tracking → `utility_meter` helper
**If no built-in helper fits, use a Template Helper — not YAML.**
Create it via the HA config flow (programmatically or in the UI:
Settings → Devices & Services → Helpers → Create Helper → Template). A flow-created helper
is UI-editable; a `template:` YAML entry needs a `template.reload` and is not.
Write `template:` YAML when the user asks for it, when neither path is available, or when
the config needs a key the flow has no field for — trigger-based templates and `attributes:`
are the coRead the full source on GitHub (opens external page)