Custom integrations
Integrations do not have to live in the core tree. ApexOS loads custom
integrations from a custom_components package inside the user's configuration
directory. The configuration directory is inserted at the front of sys.path, so
custom_components/ there is importable as a regular Python package.
<config_dir>/
└── custom_components/
└── my_integration/
├── __init__.py
├── manifest.json # must include "version"!
├── config_flow.py
├── sensor.py
├── strings.json
└── translations/
How loading works
- At startup the loader scans every directory inside
custom_components/and resolves each one that contains a valid integration (apexos/loader.py,_get_custom_components). - Custom integrations are looked up before built-in ones — a custom integration whose domain matches a built-in integration shadows it. The manifest validator emits a warning for such collisions ("Domain collides with built-in core integration"), so only do this deliberately.
- Custom integrations are not loaded in recovery mode or safe mode.
- Loading any custom integration logs a notice that the component has not been tested by ApexOS and may cause stability problems — this is expected and purely informational for users.
- A small denylist of known-broken custom integrations
(
BLOCKED_CUSTOM_INTEGRATIONSinapexos/loader.py) is blocked below a known good version.
The version key is mandatory
Unlike built-in integrations, a custom integration's manifest.json must
contain a version key. The loader refuses to load it otherwise:
The custom integration '<domain>' does not have a version key in the manifest file and was blocked from loading.
The version must be parseable as CalVer, SemVer, SimpleVer, BuildVer, or PEP 440 — an invalid value blocks loading just as a missing one does.
Custom manifests also differ from core manifests in these ways (full details in the manifest reference):
documentationmust be anhttpsURL pointing at your own docs — not the core documentation site.issue_tracker(URL) is available and recommended.import_executor(bool) is available.
How users install a custom integration
- Locate the ApexOS configuration directory.
- Create the
custom_componentsdirectory next to the main configuration file if it does not exist yet. - Copy the integration directory (the one containing
manifest.json) into it, so the path iscustom_components/<domain>/manifest.json. - Restart ApexOS. If the integration has
"config_flow": true, it can then be added from the integrations UI; discovery keys (zeroconf, dhcp, usb, …) work for custom integrations too.
Python requirements listed in the manifest's requirements key are installed
automatically into the deps directory of the configuration directory when the
integration is first set up.
Validating a custom integration
You can run the same validator the core uses against your integration directory:
python -m script.apexfest --integration-path /path/to/custom_components/<domain>
This checks the manifest schema (including the custom-specific version and
documentation rules), key ordering, translations, services, and more.