Skip to main content
This quickstart guide will help you get Home Assistant Core running locally for development and walk you through creating a simple integration.

Prerequisites

Before you begin, ensure you have:
  • Python 3.14.2 or later installed
  • Git for cloning the repository
  • A Linux, macOS, or Windows (WSL) system
  • Basic knowledge of Python and asyncio
Home Assistant Core requires Python 3.14.2 or later. Earlier versions are not supported.

Quick Setup

1

Clone the Repository

Clone the Home Assistant Core repository:
git clone https://github.com/home-assistant/core.git
cd core
2

Create a Virtual Environment

Create and activate a Python virtual environment:
python3 -m venv venv
source venv/bin/activate  # On Windows WSL: source venv/bin/activate
Using a virtual environment is highly recommended to isolate dependencies.
3

Install in Development Mode

Install Home Assistant in editable mode with development dependencies:
pip install -e .
This installs the hass command and all core dependencies.
4

Run Home Assistant

Start Home Assistant for the first time:
hass --config ./config
Home Assistant will:
  • Create a default configuration directory at ./config
  • Generate configuration.yaml with default settings
  • Start the web server on http://localhost:8123

Understanding the Command Line

The hass command (defined in homeassistant/__main__.py) provides several useful options:
# Start with a specific config directory
hass --config /path/to/config

# Enable debug mode for verbose logging
hass --debug

# Open web interface automatically on startup
hass --open-ui

# Skip pip package installation (useful for development)
hass --skip-pip

# Enable verbose file logging
hass --verbose

# Show version
hass --version
hass --config ./config

Accessing the Web Interface

Once Home Assistant is running:
  1. Open your browser to http://localhost:8123
  2. Complete the onboarding process:
    • Create an owner account
    • Set your home location
    • Configure basic settings
  3. Explore the dashboard
Use the --open-ui flag to automatically open the browser when Home Assistant starts.

Creating Your First Integration

Let’s create a simple “Hello World” integration to understand the basics.

Integration Structure

Create a new directory for your integration:
mkdir -p config/custom_components/hello_world
cd config/custom_components/hello_world

Manifest File

Create manifest.json to define your integration:
manifest.json
{
  "domain": "hello_world",
  "name": "Hello World",
  "codeowners": ["@your-username"],
  "documentation": "https://github.com/your-username/hello_world",
  "requirements": [],
  "dependencies": [],
  "version": "1.0.0"
}

Integration Code

Create __init__.py with the setup logic:
__init__.py
"""The Hello World integration."""
from __future__ import annotations

import logging
from homeassistant.core import HomeAssistant
from homeassistant.helpers.typing import ConfigType

_LOGGER = logging.getLogger(__name__)

DOMAIN = "hello_world"

async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
    """Set up the Hello World integration."""
    _LOGGER.info("Hello World integration is setting up!")
    
    # Register a service
    async def handle_say_hello(call):
        """Handle the service call."""
        name = call.data.get("name", "World")
        _LOGGER.info(f"Hello, {name}!")
        hass.states.async_set(
            f"{DOMAIN}.greeting",
            f"Hello, {name}!",
            {"friendly_name": "Last Greeting"}
        )
    
    # Register the service with Home Assistant
    hass.services.async_register(DOMAIN, "say_hello", handle_say_hello)
    
    _LOGGER.info("Hello World integration setup complete")
    return True

Add to Configuration

Add your integration to config/configuration.yaml:
configuration.yaml
# Add to configuration.yaml
hello_world:

Restart and Test

1

Restart Home Assistant

Stop Home Assistant (Ctrl+C) and restart it:
hass --config ./config
2

Call Your Service

Open the Developer Tools in the web UI (http://localhost:8123/developer-tools/service) and call your service:
service: hello_world.say_hello
data:
  name: "Developer"
3

View the State

Check the States tab in Developer Tools to see hello_world.greeting with the value “Hello, Developer!”

Understanding the Code

Let’s break down what’s happening:

The async_setup Function

async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
    """Set up the integration."""
    # Return True if setup succeeds, False otherwise
This is the entry point for YAML-configured integrations. Home Assistant calls this during bootstrap.

The HomeAssistant Object

The hass object provides access to:
  • hass.services - Service registry
  • hass.states - State machine
  • hass.bus - Event bus
  • hass.data - Shared data storage
  • hass.config - Configuration access

Registering Services

hass.services.async_register(DOMAIN, "say_hello", handle_say_hello)
This registers a service that can be called from automations, scripts, or the UI.

Setting States

hass.states.async_set(
    "hello_world.greeting",
    "Hello, Developer!",
    {"friendly_name": "Last Greeting"}
)
States are how Home Assistant tracks entity values. Each state has:
  • entity_id - Unique identifier (format: domain.object_id)
  • state - The current value (string, max 255 chars)
  • attributes - Dictionary of additional data

Adding a Sensor Platform

Let’s extend our integration with a sensor that shows random numbers. Create sensor.py:
sensor.py
"""Hello World sensor platform."""
from __future__ import annotations

import random
from homeassistant.components.sensor import SensorEntity
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType

async def async_setup_platform(
    hass: HomeAssistant,
    config: ConfigType,
    async_add_entities: AddEntitiesCallback,
    discovery_info: DiscoveryInfoType | None = None,
) -> None:
    """Set up the Hello World sensor platform."""
    async_add_entities([HelloWorldSensor()], True)

class HelloWorldSensor(SensorEntity):
    """Representation of a Hello World sensor."""
    
    def __init__(self) -> None:
        """Initialize the sensor."""
        self._attr_name = "Hello World Random"
        self._attr_unique_id = "hello_world_random"
        self._attr_native_value = None
    
    async def async_update(self) -> None:
        """Fetch new state data for the sensor."""
        self._attr_native_value = random.randint(1, 100)
Update configuration.yaml to enable the sensor:
configuration.yaml
sensor:
  - platform: hello_world

Next Steps

Now that you have a working development environment:

Installation Guide

Learn about detailed installation options and requirements

Configuration

Explore Home Assistant configuration options

Developer Docs

Read the comprehensive developer documentation

Integration Development

Deep dive into creating integrations

Common Issues

Python Version Mismatch: Ensure you’re using Python 3.14.2+. Check with python3 --version.
Port Already in Use: If port 8123 is taken, Home Assistant will fail to start. Stop other services or configure a different port.
Use hass --debug for detailed logs when troubleshooting issues.

Build docs developers (and LLMs) love