A lightweight, fully typed home automation framework built on MQTT and Bun. Write automations as TypeScript classes — no YAML, no UI, just code.
This project is developed with the assistance of AI tools (code generation, documentation, and testing).
The engine library is @ts-ha/core; the runner (ts-ha run) is @ts-ha/cli.
bun add @ts-ha/core @ts-ha/cliOr clone and run from source:
git clone https://github.com/Supporterino/TypeScript-Home-Automation.git
cd TypeScript-Home-Automation && bun install && bun run devRequires Bun and an MQTT broker (e.g. Mosquitto).
Run an engine with ts-ha run, which loads automations from ./automations by
default (create the directory; no examples ship with the packages):
mkdir -p automations
bunx ts-ha run --automations ./automationsOr embed the engine in your own project:
// src/index.ts
import { createEngine } from "@ts-ha/core";
const engine = createEngine({
automationsDir: new URL("./automations", import.meta.url).pathname,
});
process.on("SIGINT", async () => { await engine.stop(); process.exit(0); });
await engine.start();// automations/motion-light.ts
import { Automation, type Trigger, type TriggerContext } from "@ts-ha/core";
import type { OccupancyPayload } from "@ts-ha/shared/types";
export default class MotionLight extends Automation {
readonly name = "motion-light";
readonly triggers: Trigger[] = [
{ type: "mqtt", topic: "zigbee2mqtt/hallway_sensor",
filter: (p) => (p as OccupancyPayload).occupancy === true },
];
async execute(_ctx: TriggerContext): Promise<void> {
this.mqtt.publishToDevice("hallway_light", { state: "ON", brightness: 254 });
}
}| Variable | Default | Description |
|---|---|---|
MQTT_HOST |
localhost |
MQTT broker hostname |
LOG_LEVEL |
info |
trace · debug · info · warn · error |
HTTP_PORT |
8080 |
HTTP server port (0 = disabled) |
WEB_UI_ENABLED |
false |
Enable the web UI dashboard (parsed by @ts-ha/web-ui; requires the optional peer installed) |
DEVICE_REGISTRY_ENABLED |
false |
Enable Zigbee device discovery and state tracking |
See Configuration for all variables.
With the web UI enabled, a home can run one or more wall-mounted panels. Each is
a named wall profile — a curated composition of widgets (clock, weather,
energy, room and device controls, favorites, status, scene buttons) — rendered
full-bleed, with no dashboard chrome, at {WEB_UI_PATH}/wall/:name. Profiles are
created and configured at {WEB_UI_PATH}/walls, persist across restarts in the
reserved state namespace, and are served over /api/walls. The wall is composed
to be glanceable from across a room: cards size to their declared span, ambient
readouts (clock, weather, energy, status) render chrome-less while control
widgets (room, favorites, device, scene) render as touch tiles, and device tiles
run in a kiosk mode that drops device-management and open-detail affordances
while keeping the same actuation and state semantics as the dashboard. Screen
wake-lock, fullscreen/PWA, and burn-in mitigation are intentionally left to the
host tablet.
See Web UI → Wall displays.
| Getting Started | Install, configure, first automation |
| Writing Automations | Triggers, services, lifecycle hooks |
| API Reference | All public classes, types, and methods |
| Device Registry | Zigbee device discovery, state tracking, nice names |
| Configuration | All environment variables |
| CLI Reference | ts-ha commands |
| Web UI | Browser dashboard |
| Deployment | Docker, Kubernetes, production setup |
| Architecture | How the engine works |
| Troubleshooting | Common issues and solutions |
| Contributing | Dev setup, conventions |
Third-party attributions — including the wall's device-card design, ported from Lovelace Mushroom (Apache-2.0) — are recorded in THIRD_PARTY_NOTICES.md.