Repository structure
Where the files of each type go in your repository, what the Marketplace installs from it, and where that ends up in the user's configuration.
Every type needs a public GitHub repository with a hacs.json and a README in the root. Beyond that, each type has its own layout. A repository holds one item of one type.
| What | Why |
|---|---|
| Public repository on GitHub | The Marketplace and HACS only read public GitHub repositories. |
hacs.json in the root |
The Marketplace can not install or update a repository without it. See hacs.json. |
README.md |
What users read before they install. The Marketplace shows it on the page of your repository. |
| A description on GitHub | Shown in the list of the Marketplace. Required for the catalog. |
| Topics on GitHub | Help users find your repository. Required for the catalog. |
| Issues turned on | Where users report problems. Required for the catalog. |
| GitHub releases | Recommended for every type, required for templates and for the catalog. See releases and updates. |
custom_components/awesome/__init__.py
custom_components/awesome/manifest.json
custom_components/awesome/sensor.py
custom_components/awesome/brand/icon.png
hacs.json
README.md- One integration per repository, in
custom_components/<domain>/. The Marketplace takes the first folder incustom_components/. - Everything the integration needs is inside that folder.
manifest.jsonhas adomainwith only lowercase letters, numbers, underscores, and hyphens, and aversion. HACS also requiresdocumentation,issue_tracker,codeowners, andname.- With
content_in_root, the files of the integration are in the root of the repository instead. - Installed to
custom_components/<domain>/.
See custom integrations.
dist/awesome-card.js
hacs.json
README.md- A JavaScript file named after the repository:
<name>.js,<name>.umd.js, or<name>-bundle.js. For<name>.js, the name is also tried withoutlovelace-in it. Any other name goes infilenameinhacs.json. - The file is attached to your latest release, or is in the root, or in
dist. - Files the module needs, like images, go in
distwith it, or are attached to the release. - Installed to
www/community/<repository name>/, and added as a dashboard resource.
See dashboard cards and plugins.
themes/awesome.yaml
hacs.json
README.md- A YAML file in
themes/. HACS manages one theme file per repository. - With
content_in_root, the file is in the root of the repository instead. - Valid YAML, without tags like
!includeor!secret. - Installed to
themes/<name of the theme file>/.
See themes.
awesome.jinja
hacs.json
README.md- One
.jinjafile in the root, named infilenameinhacs.json. Not in a subfolder. - UTF-8, and smaller than 5 MiB.
- No
zip_release. - Installed to
custom_templates/.
See template macros.
HACS also handles AppDaemon apps (apps/) and Python scripts (python_scripts/), and the catalog has lists for them. The Marketplace does not install either. Starting with 2026.11, Home Assistant also blocks the HACS custom integration, because the Marketplace replaces it. So on 2026.11 and later, neither installs them.
The Marketplace also refuses repositories with apps for Home Assistant OS. Those are added as an app repository under Settings > Apps instead: see create and share a repository.