Set up your development environment
Get a working Home Assistant Core development setup, with the development container or a manual install on Linux, macOS, or Windows.
You need a development environment to run Home Assistant from source, run the tests, and run the linters. There are two ways to get one:
- The development container (recommended): Visual Studio Code builds a Docker container with the right Python version, every dependency, and the linters already set up. You get the same setup on Linux, macOS, and Windows. The exception is access to hardware like USB sticks, see the note below.
- A manual setup: you install Python and the system libraries yourself, and create a virtual environment. Use this if you do not want to use Docker or Visual Studio Code.
- Visual Studio Code
- Git
- Docker. How you install it depends on your operating system, see below.
The container makes it harder to use hardware like USB sticks or the Bluetooth adapter of your computer. On a Linux host, you can pass them through to the container. On Windows, Docker runs inside WSL, which has no access to USB devices on its own: you first attach a device to WSL with usbipd-win. On macOS, the container cannot access that hardware directly. Docker Desktop can share USB devices over the network with USB/IP, but that takes extra setup.
Install the Docker Engine with the instructions for your distribution. Then follow the post-installation steps, so you can use Docker without root.
Install Docker Desktop for Mac.
On Windows, everything runs inside WSL2, the Windows Subsystem for Linux.
-
Install WSL2 with the default Ubuntu distribution. In a Windows terminal, run:
Shellwsl --install -
Check that your distribution runs on WSL version 2:
Shellwsl -l -vIf it shows version 1, convert it with
wsl --set-version <distro name> 2. -
Docker Engine runs as a systemd service, so enable systemd. Start the WSL shell with
wsl, and add this to/etc/wsl.conf(withsudo):INI[boot] systemd=true -
Restart WSL from the Windows terminal with
wsl --shutdown, and start it again. -
Inside WSL, follow the Linux instructions above to install Docker Engine.
From here on, do everything inside WSL, including cloning the repository. Code on the Windows side of the file system runs into permission problems.
-
Fork the core repository on GitHub.
-
Clone your fork, add the Home Assistant repository as
upstream, and open it in Visual Studio Code:Shellgit clone https://github.com/YOUR_GITHUB_USERNAME/core cd core git remote add upstream https://github.com/home-assistant/core.git code . -
Visual Studio Code detects the container configuration and asks if you want to Reopen in Container. Select it. If it asks to install the Dev Containers extension, install it.
-
Wait for the container to build. The first time takes several minutes. When it is done, it runs
script/setup, which installs all requirements and the Git hooks for the linters.
To check that everything works, open the Command Palette (Ctrl+Shift+P, or Shift+Command+P on macOS), select Tasks: Run Task, then Run Home Assistant Core. When the output in the terminal slows down, open http://localhost:8123. You should see the onboarding screen.
To come back to the container later, open Visual Studio Code, select Remote Explorer in the sidebar, and pick the container.
The container comes with tasks for the things you do most. Open the Command Palette, select Tasks: Run Task, and pick one:
| Task | What it does |
|---|---|
| Run Home Assistant Core | Starts Home Assistant with the configuration in config/. |
| Pytest | Runs the full test suite. |
| Pytest (changed tests only) | Runs only the test files you changed. |
| Code Coverage | Runs the tests of one integration, with a coverage report. |
| Update syrupy snapshots | Updates the snapshots of one integration. |
| Prek | Runs the linters on your changes. |
| Generate Requirements | Updates requirements_all.txt after you changed a dependency. |
| Install all (test & production) Requirements | Installs every requirement again. |
| Compile English translations | Turns strings.json files into the English translations. |
| Create new integration | Starts the scaffold that generates a new integration. |
To restart a task that is still running, select Tasks: Restart Running Task.
The container comes with debug configurations. Press F5 to start Home Assistant in the debugger, and it stops on any breakpoint you set. The Run and Debug view also has configurations to debug the current test file, or to attach to a running instance.
To debug an instance that runs elsewhere, like your production system, use the debugpy integration.
Starting with Home Assistant 2026.11, you can also look around inside a running Home Assistant without a debugger, with the debug console under Settings > Tools > Debug console. It runs Python code with hass available, shows results as objects you can expand, and completes code while you type. For example, to look at the state of the sun:
hass.states.get("sun.sun")The debug console is enabled from the start on development and nightly versions, like the one in this container. On beta and stable versions from 2026.11 on, add debug_console: to your configuration.yaml first, and restart Home Assistant; see the Debug console integration. Code runs in the event loop of Home Assistant, so await asynchronous calls, and run blocking work with await hass.async_add_executor_job(...).
A container that fails to build is often based on an outdated fork.
- Make sure your fork is up to date with the
devbranch of Home Assistant. - Clean the Docker build cache with
docker buildx prune. - If that does not help, select Open configuration in recovery devcontainer, run
git pull upstream devin its terminal, then select Dev Containers: Rebuild Container from the Command Palette.
Core needs a recent Python: requires-python in its pyproject.toml asks for 3.14.2 or newer. The Python that comes with your operating system is often older. If you create the virtual environment with an older Python, it does not work: install the right version, delete the .venv folder, and run the setup again.
Home Assistant and its requirements need a few system libraries and build tools.
On Ubuntu or Debian:
sudo apt-get update
sudo apt-get install autoconf libssl-dev libxml2-dev libxslt1-dev libjpeg-dev \
libffi-dev libudev-dev zlib1g-dev pkg-config libavformat-dev \
libavcodec-dev libavdevice-dev libavutil-dev libswscale-dev \
libswresample-dev libavfilter-dev ffmpeg libgammu-dev \
build-essentialOn Fedora:
sudo dnf update
sudo dnf install autoconf openssl-devel libxml2-devel libxslt-devel \
libjpeg-turbo-devel libffi-devel systemd-devel zlib-devel \
pkgconf-pkg-config libavformat-free-devel libavcodec-free-devel \
libavdevice-free-devel libavutil-free-devel libswscale-free-devel \
ffmpeg-free-devel libavfilter-free-devel ffmpeg-free gcc gcc-c++ \
cmakeOn Arch or Manjaro:
sudo pacman -Sy base-devel autoconf libxml2 libxslt libjpeg-turbo \
libffi systemd zlib pkgconf ffmpeg gcc cmakeOn macOS, install Homebrew and use it to install the dependencies:
brew install autoconf ffmpeg cmake makeSome dependencies, like cryptography and orjson, contain Rust code. If there is no prebuilt package for your platform, they are built from source, and that needs a Rust toolchain. If the setup fails because rustc or cargo is missing, run brew install rust.
On NixOS, put this default.nix in the repository and activate it, for example with direnv:
let
pkgs = import <nixpkgs> { };
in
pkgs.mkShell {
packages = with pkgs; [
autoconf
clang
cmake
ffmpeg
ffmpeg.dev
gammu
libffi.dev
libjpeg.dev
libxml2.dev
libxslt.dev
openssl_3.dev
pkg-config
python314
zlib.dev
];
env = {
LD_LIBRARY_PATH = "${pkgs.libjpeg.out}/lib";
};
}On Windows, install WSL with Ubuntu, and follow the Ubuntu instructions inside WSL. Keep all your code inside WSL.
The easiest way to get the right Python is uv, the package manager core uses. Install it with the official installer:
curl -LsSf https://astral.sh/uv/install.sh | shYou do not have to install Python yourself after that. The core repository has a .python-version file with the exact version the development container uses, and uv reads it: when the setup script creates the virtual environment, uv downloads that version if you do not have it yet. To install it up front, run uv python install in the repository folder, after you cloned it.
If uv reports that it found no download for the required Python version, your uv is too old. Run the installer again to update it.
On NixOS, python314 in default.nix provides Python, and you do not need uv for it.
Fork the core repository, clone your fork, and add the Home Assistant repository as upstream:
git clone https://github.com/YOUR_GITHUB_USERNAME/core
cd core
git remote add upstream https://github.com/home-assistant/core.gitThen run the setup script:
script/setupIf no virtual environment is active, it creates one in .venv, with uv if you have it, and with python3 -m venv otherwise. If a virtual environment is active, it uses that one instead. Then it installs all requirements, installs the Git hooks for the linters, and creates a configuration in the config folder.
Activate the virtual environment in every new terminal:
source .venv/bin/activateThen start Home Assistant with the configuration from the config folder:
hass -c configOpen http://localhost:8123 to see it.
If hass crashes with SIGKILL on macOS, your terminal app probably lacks Bluetooth permission. Add it under System Settings > Privacy & Security > Bluetooth.
If http://localhost:8123 does not open from Windows, find the address of WSL with ip addr show eth0, and use the inet address without the part after the slash. For example, 172.20.37.6/20 becomes http://172.20.37.6:8123.
By default WSL uses NAT networking, which keeps Home Assistant from discovering devices on your network. Mirrored mode networking gives WSL the same network interfaces as Windows, including multicast, so discovery with mDNS works.
If you use an AI coding tool, it doesn't have to guess how core works. The repository has an AGENTS.md file with instructions for agents, and skills in .claude/skills/, like ha-integration-knowledge for building integrations and ha-quality-scale-verify for checking quality scale rules. They are a useful read for humans too.
You stay responsible for the result: see the AI policy. Contribute with AI tools lists every skill, and walks through fixing a bug and building an integration up to Bronze with them.
- Running the tests: run the tests before you open a pull request.
- Linters, hassfest, and CI: what runs when you commit.