Skip to main content

Integration Manifest

Every Home Assistant integration requires a manifest.json file that describes its metadata, dependencies, and capabilities. This file is essential for integration discovery and loading.

Basic Structure

The manifest file must be named manifest.json and placed in the root of your integration directory:
homeassistant/components/your_integration/
└── manifest.json

Required Fields

domain

The unique identifier for your integration:
{
  "domain": "mqtt"
}
The domain must match your integration’s directory name and be lowercase with underscores only.

name

The human-readable name displayed in the UI:
{
  "name": "MQTT"
}

codeowners

GitHub usernames responsible for maintaining the integration:
{
  "codeowners": ["@emontnemery", "@jbouwh", "@bdraco"]
}
Code owners are automatically notified of PRs affecting their integration.

documentation

URL to the integration’s documentation:
{
  "documentation": "https://www.home-assistant.io/integrations/mqtt"
}

Integration Metadata

integration_type

Defines the integration’s purpose:
{
  "integration_type": "service"
}
Available types from loader.py:250:
  • entity - Provides entity platforms
  • device - Represents physical devices
  • hardware - Interfaces with hardware
  • helper - Utility functions
  • hub - Central hub connection (default)
  • service - External service connectivity
  • system - Core functionality
  • virtual - Virtual/computed entities

iot_class

Describes how the integration communicates:
{
  "iot_class": "local_push"
}
Options:
  • local_push - Device pushes updates locally (best)
  • local_polling - Polls device locally
  • cloud_push - Device pushes updates via cloud
  • cloud_polling - Polls cloud API
  • calculated - Calculated values, no external source
Local push is preferred for the best user experience and minimal latency.

quality_scale

Indicates code quality level:
{
  "quality_scale": "platinum"
}
Levels:
  • platinum - Highest quality, comprehensive tests, excellent code
  • gold - High quality, good test coverage
  • silver - Good quality, basic tests
  • internal - Core Home Assistant integrations
  • custom - Custom integrations (automatic for custom components)

Dependencies

dependencies

Integrations that must be loaded first:
{
  "dependencies": ["file_upload", "http"]
}
From the MQTT manifest (homeassistant/components/mqtt/manifest.json:7):
{
  "domain": "mqtt",
  "dependencies": ["file_upload", "http"]
}
If a dependency fails to load, your integration will not load either.

after_dependencies

Integrations that should load first if present (soft dependency):
{
  "after_dependencies": ["hassio"]
}
From MQTT (homeassistant/components/mqtt/manifest.json:4):
{
  "after_dependencies": ["hassio"]
}
Unlike dependencies, these are optional. Your integration loads even if they’re missing.

Python Requirements

requirements

Python packages required by your integration:
{
  "requirements": ["paho-mqtt==2.1.0"]
}
Real example from MQTT (homeassistant/components/mqtt/manifest.json:12):
{
  "requirements": ["paho-mqtt==2.1.0"]
}
Always pin exact versions to ensure reproducible installs.

Configuration

config_flow

Enables UI-based configuration:
{
  "config_flow": true
}
When enabled, users can configure your integration through the UI. You must implement config_flow.py. From MQTT (homeassistant/components/mqtt/manifest.json:6):
{
  "config_flow": true
}

Config Flow Implementation

Learn how to implement config_flow.py

single_config_entry

Restricts integration to one configuration entry:
{
  "single_config_entry": true
}
Example from MQTT (homeassistant/components/mqtt/manifest.json:13):
{
  "single_config_entry": true
}
Use this when multiple entries would cause conflicts or make no sense.

Discovery

These fields enable automatic discovery of devices:

zeroconf

Zeroconf/mDNS service types to watch:
{
  "zeroconf": [
    "_mqtt._tcp.local.",
    {
      "type": "_homekit._tcp.local.",
      "properties": {"md": "homekit*"}
    }
  ]
}

ssdp

SSDP discovery patterns:
{
  "ssdp": [
    {
      "manufacturer": "Philips",
      "modelName": "Philips hue bridge"
    }
  ]
}

bluetooth

Bluetooth device matchers:
{
  "bluetooth": [
    {
      "local_name": "MyDevice*",
      "service_uuid": "0000180a-0000-1000-8000-00805f9b34fb"
    }
  ]
}

dhcp

DHCP discovery patterns:
{
  "dhcp": [
    {
      "hostname": "mydevice*",
      "macaddress": "001122*"
    }
  ]
}

mqtt

MQTT discovery topics:
{
  "mqtt": [
    "homeassistant/status"
  ]
}

usb

USB device matchers:
{
  "usb": [
    {
      "vid": "10C4",
      "pid": "EA60"
    }
  ]
}

homekit

HomeKit device models:
{
  "homekit": {
    "models": ["BSB002"]
  }
}

Advanced Options

version

Required for custom integrations:
{
  "version": "1.2.3"
}
Custom integrations without a version will not load. Use semantic versioning (major.minor.patch).

import_executor

Controls where the integration is imported:
{
  "import_executor": true
}
Default is true (imports in executor thread for better performance). From loader.py:864:
@cached_property
def import_executor(self) -> bool:
    """Import integration in the executor."""
    # If the integration does not explicitly set import_executor,
    # we default to True.
    return self.manifest.get("import_executor", True)
Set to false only if your integration must be imported in the event loop. This is rare.

issue_tracker

URL for reporting issues:
{
  "issue_tracker": "https://github.com/home-assistant/core/issues"
}

loggers

List of Python loggers used:
{
  "loggers": ["paho.mqtt", "paho.mqtt.client"]
}
Helps users configure logging for your integration’s dependencies.

disabled

Reason the integration is disabled:
{
  "disabled": "Integration removed due to API shutdown"
}
Disabled integrations are not loaded.

Complete Examples

MQTT Integration (Platinum Quality)

Real manifest from homeassistant/components/mqtt/manifest.json:
{
  "domain": "mqtt",
  "name": "MQTT",
  "after_dependencies": ["hassio"],
  "codeowners": ["@emontnemery", "@jbouwh", "@bdraco"],
  "config_flow": true,
  "dependencies": ["file_upload", "http"],
  "documentation": "https://www.home-assistant.io/integrations/mqtt",
  "integration_type": "service",
  "iot_class": "local_push",
  "quality_scale": "platinum",
  "requirements": ["paho-mqtt==2.1.0"],
  "single_config_entry": true
}

HTTP Integration (System)

Real manifest from homeassistant/components/http/manifest.json:
{
  "domain": "http",
  "name": "HTTP",
  "codeowners": ["@home-assistant/core"],
  "documentation": "https://www.home-assistant.io/integrations/http",
  "integration_type": "system",
  "iot_class": "local_push",
  "quality_scale": "internal"
}

Demo Integration (Testing)

Real manifest from homeassistant/components/demo/manifest.json:
{
  "domain": "demo",
  "name": "Demo",
  "codeowners": ["@home-assistant/core"],
  "dependencies": ["conversation", "group", "zone"],
  "documentation": "https://www.home-assistant.io/integrations/demo",
  "iot_class": "calculated",
  "quality_scale": "internal",
  "single_config_entry": true
}

Manifest Validation

Home Assistant validates manifests at startup. Common errors:
Invalid domain: Domain must match directory name and be lowercase.Missing version: Custom integrations must have a version field.Invalid IoT class: Must be one of the predefined values.Missing codeowners: All integrations should have maintainers.

Manifest Type Definition

From loader.py:239:
class Manifest(TypedDict, total=False):
    """Integration manifest."""
    name: str
    disabled: str
    domain: str
    integration_type: Literal[
        "entity", "device", "hardware", "helper", 
        "hub", "service", "system", "virtual"
    ]
    dependencies: list[str]
    after_dependencies: list[str]
    requirements: list[str]
    config_flow: bool
    documentation: str
    issue_tracker: str
    quality_scale: str
    iot_class: str
    # ... more fields

Next Steps

Creating Components

Build your integration’s main component

Config Flow

Implement UI-based configuration

Build docs developers (and LLMs) love