# Home Assistant Runtime Configuration Structure and Runner Injection

> Understand the Home Assistant runtime configuration structure and how it's injected into the runner. Learn how flags and environment settings populate the core config object.

- Repository: [Home Assistant/core](https://github.com/home-assistant/core)
- Tags: internals
- Published: 2026-02-28

---

**The `RuntimeConfig` dataclass bundles all command-line flags and environment settings into a single immutable object that flows from the CLI parser through [`homeassistant/runner.py`](https://github.com/home-assistant/core/blob/main/homeassistant/runner.py) to [`homeassistant/bootstrap.py`](https://github.com/home-assistant/core/blob/main/homeassistant/bootstrap.py), where individual fields populate the core `HomeAssistant` config object.**

The `home-assistant/core` repository uses a centralized runtime configuration pattern to manage startup parameters cleanly. When you launch Home Assistant via the `hass` command, your arguments are encapsulated in a `RuntimeConfig` instance that travels unchanged through the initialization pipeline. This design ensures that configuration directory paths, logging preferences, and debug flags remain consistent from process startup through core initialization.

## RuntimeConfig Dataclass Structure

The `RuntimeConfig` class is defined in [`homeassistant/runner.py`](https://github.com/home-assistant/core/blob/main/homeassistant/runner.py) using `@dataclasses.dataclass(slots=True)`, creating a lightweight immutable container. It aggregates every launch parameter required to configure the core application:

- **config_dir**: Path to the configuration directory (defaults to `/config`)
- **skip_pip**: Boolean to disable automatic installation of missing Python dependencies
- **skip_pip_packages**: List of specific pip packages to skip during setup
- **recovery_mode**: Boolean forcing recovery mode when configuration parsing fails
- **verbose**: Boolean enabling verbose logging output
- **log_rotate_days**: Optional integer specifying retention days for log files
- **log_file**: Optional string path for the destination log file
- **log_no_color**: Boolean disabling color codes in terminal output
- **debug**: Boolean running the event loop in debug mode and setting `hass.config.debug`
- **open_ui**: Boolean triggering browser opening after core startup
- **safe_mode**: Boolean starting Home Assistant in safe mode with most integrations disabled

## Configuration Flow from CLI to Core

### CLI Construction

The command-line parser in [`homeassistant/__main__.py`](https://github.com/home-assistant/core/blob/main/homeassistant/__main__.py) constructs a `RuntimeConfig` instance from supplied flags and environment variables. This object serves as the single source of truth for the entire startup sequence.

### Runner Entry Point

The `run()` function in [`homeassistant/runner.py`](https://github.com/home-assistant/core/blob/main/homeassistant/runner.py) receives the `RuntimeConfig` and initializes the asyncio environment:

```python
_enable_posix_spawn()
set_open_file_descriptor_limit()
asyncio.set_event_loop_policy(
    HassEventLoopPolicy(runtime_config.debug)
)
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
return loop.run_until_complete(
    setup_and_run_hass(runtime_config)
)

```

The `debug` flag is immediately handed to `HassEventLoopPolicy`, which configures the asyncio loop for debug tracing before the core initializes.

### Bootstrap Initialization

Inside `setup_and_run_hass()`, the coroutine forwards `RuntimeConfig` to `bootstrap.async_setup_hass()` in [`homeassistant/bootstrap.py`](https://github.com/home-assistant/core/blob/main/homeassistant/bootstrap.py). The bootstrap layer extracts individual fields to configure the `HomeAssistant` core object:

```python
hass = core.HomeAssistant(runtime_config.config_dir)
...
hass.config.debug = runtime_config.debug
hass.config.safe_mode = runtime_config.safe_mode
hass.config.skip_pip = runtime_config.skip_pip
hass.config.skip_pip_packages = runtime_config.skip_pip_packages

```

This wiring occurs early in `async_setup_hass`, before any integrations load, ensuring the core configuration object reflects command-line intentions.

### Logging Configuration

The bootstrap module forwards logging-related fields (`verbose`, `log_rotate_days`, `log_file`, `log_no_color`) to `async_enable_logging`, configuring the root logger before component initialization begins.

### Core Execution

After bootstrap completes, `setup_and_run_hass` calls `await hass.async_run()`, which starts the core event loop, background tasks, and HTTP/Web UI using the parameters propagated from the original `RuntimeConfig`.

## Practical Implementation Examples

### Manually Building RuntimeConfig

For tests or custom scripts, you can manually construct a `RuntimeConfig` and invoke the runner directly:

```python
from homeassistant.runner import RuntimeConfig, run

# Minimal configuration pointing to an existing config directory

config = RuntimeConfig(
    config_dir="/home/user/.homeassistant",
    verbose=True,
    debug=True,
    safe_mode=False,
    log_file="/tmp/hass.log",
)

# Run Home Assistant in the current process (blocking until exit)

exit_code = run(config)
print("Home Assistant terminated with code", exit_code)

```

This mirrors how the internal `hass` command creates the configuration object.

### Accessing Config in Integrations

Custom integrations access runtime parameters through the `hass.config` object, which received values from `RuntimeConfig` during bootstrap:

```python
def async_setup_entry(hass, entry):
    # Values propagated from original RuntimeConfig by bootstrap.async_setup_hass

    if hass.config.debug:
        _LOGGER.debug("Running in debug mode")
    if hass.config.safe_mode:
        _LOGGER.info("Safe mode active – only core integrations loading")
    return True

```

Note that integrations cannot access the original `RuntimeConfig` directly; they must use the `hass.config` namespace.

## Key Source Files

- **[`homeassistant/runner.py`](https://github.com/home-assistant/core/blob/main/homeassistant/runner.py)**: Defines `RuntimeConfig`, the `run()` entry point, and `HassEventLoopPolicy`
- **[`homeassistant/bootstrap.py`](https://github.com/home-assistant/core/blob/main/homeassistant/bootstrap.py)**: Consumes `RuntimeConfig` to configure the core `HomeAssistant` object and logging
- **[`homeassistant/__main__.py`](https://github.com/home-assistant/core/blob/main/homeassistant/__main__.py)**: Parses CLI arguments and instantiates `RuntimeConfig`
- **[`homeassistant/util/resource.py`](https://github.com/home-assistant/core/blob/main/homeassistant/util/resource.py)**: Provides `set_open_file_descriptor_limit()` used by the runner

## Summary

- **RuntimeConfig** is an immutable dataclass defined in [`homeassistant/runner.py`](https://github.com/home-assistant/core/blob/main/homeassistant/runner.py) that encapsulates all startup parameters including paths, logging settings, and mode flags.
- The configuration flows unidirectionally from CLI parser → `run()` → `setup_and_run_hass()` → `bootstrap.async_setup_hass()`.
- The bootstrap layer maps `RuntimeConfig` fields to `hass.config` attributes, making them available to integrations.
- The `debug` flag immediately affects the asyncio event loop policy before core initialization.
- Direct instantiation of `RuntimeConfig` allows programmatic Home Assistant startup for testing and custom deployments.

## Frequently Asked Questions

### What is the RuntimeConfig class in Home Assistant?

`RuntimeConfig` is a Python dataclass defined in [`homeassistant/runner.py`](https://github.com/home-assistant/core/blob/main/homeassistant/runner.py) that acts as an immutable container for all command-line arguments and environment settings required to launch Home Assistant. It uses `slots=True` for memory efficiency and contains fields for configuration directories, logging options, and operational modes like safe mode or debug mode.

### How does the debug flag affect the event loop?

When `runtime_config.debug` is `True`, the runner passes this flag to `HassEventLoopPolicy` in [`homeassistant/runner.py`](https://github.com/home-assistant/core/blob/main/homeassistant/runner.py), which configures the asyncio event loop for debug tracing before the loop is created. This enables warnings for slow callbacks and unawaited coroutines during the core initialization phase.

### Can integrations access the original RuntimeConfig object?

No, integrations cannot access the original `RuntimeConfig` instance directly. The bootstrap module in [`homeassistant/bootstrap.py`](https://github.com/home-assistant/core/blob/main/homeassistant/bootstrap.py) extracts values from `RuntimeConfig` and assigns them to the `hass.config` object during `async_setup_hass()`. Integrations must read runtime parameters from `hass.config` attributes such as `hass.config.debug` or `hass.config.safe_mode`.

### Where is the configuration directory path defined during startup?

The `config_dir` path originates from command-line arguments parsed in [`homeassistant/__main__.py`](https://github.com/home-assistant/core/blob/main/homeassistant/__main__.py), is stored in `RuntimeConfig`, and passed to `core.HomeAssistant(runtime_config.config_dir)` in [`homeassistant/bootstrap.py`](https://github.com/home-assistant/core/blob/main/homeassistant/bootstrap.py). This occurs early in the bootstrap sequence, establishing the base path for all YAML configuration files and storage directories.