homey-app

Build, scaffold, debug, and publish apps for the Homey smart home platform using the Homey Apps SDK v3. Use this skill whenever the user mentions Homey, Homey Pro, Homey Cloud, Homey app development, Homey CLI, Homey Compose, Homey Flow cards, Homey device drivers, Homey capabilities, Homey widgets, Homey pairing, or any smart home app development targeting the Homey platform. Also trigger when the user wants to integrate a device brand or cloud service with Homey, create Flow automations, build dashboard widgets, or publish to the Homey App Store. Even if the user just says "I want to make a Homey app" or mentions a device they want to control with Homey, use this skill.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "homey-app" with this command: npx skills add dvflw/homey-app-skill/dvflw-homey-app-skill-homey-app

Homey Apps SDK — Skill Guide

This skill helps you build apps for the Homey smart home platform. A Homey app is a Node.js bundle that runs locally on Homey Pro (or in the cloud on Homey Cloud). Apps add Devices, Flow cards, Widgets, and more to the Homey ecosystem.

Key Concepts

SDK version: Always use SDK v3 ("sdk": 3 in the manifest). SDK v3 is async/await everywhere.

Node.js: As of Homey v12.9.0, all platforms run Node.js 22.

Homey Compose: The build system that splits the monolithic app.json manifest into smaller *.compose.json files. Never edit /app.json directly — edit the compose files instead.

Three core classes you extend in every app:

  • Homey.App — exported from /app.js, instantiated once on app start
  • Homey.Driver — exported from /drivers/<id>/driver.js, manages pairing and all device instances
  • Homey.Device — exported from /drivers/<id>/device.js, represents a single paired device

Homey CLI (npx homey) is the primary development tool:

  • homey app create — scaffold a new app
  • homey app run — run & debug live on a Homey (uninstalls on quit)
  • homey app install — install persistently for testing
  • homey app publish — publish to the Homey App Store
  • homey app driver create — interactively add a driver
  • homey app flow create — interactively add a Flow card
  • homey app validate — check manifest validity

Project Structure (Homey Compose)

com.example.myapp/
├─ .homeycompose/
│  ├─ app.json                         # Core manifest properties
│  ├─ capabilities/
│  │  └─ <custom_cap_id>.json          # Custom capability definitions
│  ├─ flow/
│  │  ├─ triggers/<id>.json            # App-level Flow trigger cards
│  │  ├─ conditions/<id>.json          # App-level Flow condition cards
│  │  └─ actions/<id>.json             # App-level Flow action cards
│  ├─ discovery/
│  │  └─ <id>.json                     # LAN discovery strategies (mDNS, SSDP, MAC)
│  └─ locales/
│     └─ en.json                       # App-level translations
├─ assets/
│  ├─ icon.svg                         # App icon (SVG)
│  └─ images/
│     ├─ small.png (250x175)
│     ├─ large.png (500x350)
│     └─ xlarge.png (1000x700)
├─ drivers/
│  └─ <driver_id>/
│     ├─ assets/
│     │  ├─ icon.svg                   # Driver icon
│     │  └─ images/ (small, large, xlarge)
│     ├─ device.js                     # Device class
│     ├─ driver.js                     # Driver class
│     ├─ driver.compose.json           # Driver manifest
│     ├─ driver.flow.compose.json      # Driver-specific Flow cards (optional)
│     └─ driver.settings.compose.json  # Device settings (optional)
├─ widgets/
│  └─ <widget_id>/
│     ├─ public/
│     │  └─ index.html                 # Widget frontend
│     ├─ api.js                        # Widget API handlers
│     ├─ widget.compose.json           # Widget definition
│     ├─ preview-dark.png              # Widget preview (dark)
│     └─ preview-light.png             # Widget preview (light)
├─ locales/
│  ├─ en.json
│  └─ nl.json
├─ settings/
│  └─ index.html                       # App settings page (optional)
├─ api.js                              # App Web API (optional, Pro only)
├─ app.js                              # App class
├─ env.json                            # Secret environment variables (gitignored!)
├─ README.txt                          # App Store long description (plain text, no markdown)
└─ .homeyignore                        # Files to exclude from publishing

How to Use This Skill

When creating a Homey app, follow this workflow:

  1. Determine the integration type — Is it a LAN device (Wi-Fi/mDNS/SSDP), cloud API (OAuth2/webhooks), or wireless protocol (Z-Wave, Zigbee, 433MHz, BLE, IR, Matter)?
  2. Read the relevant reference file from references/ for detailed patterns:
    • references/app-and-manifest.md — App class, manifest, settings, environment, i18n, permissions
    • references/drivers-and-devices.md — Driver/Device classes, pairing, capabilities, settings, discovery
    • references/flow-cards.md — Triggers, conditions, actions, arguments, tokens, device Flow cards
    • references/widgets.md — Dashboard widgets, widget settings, widget API
    • references/wireless-and-cloud.md — Wi-Fi/LAN discovery, OAuth2, webhooks, Z-Wave, Zigbee, BLE
    • references/publishing.md — App Store guidelines, icons, images, publishing flow
  3. Scaffold the project following the Homey Compose structure above
  4. Write the code using SDK v3 patterns (async/await, this.homey.* managers)
  5. Validate with homey app validate --level=publish

Scaffolding a New App

When the user asks to create a new Homey app, generate the full file set. At minimum you need:

  • /.homeycompose/app.json with id, version, compatibility, sdk, name, description, category, etc.
  • /app.js extending Homey.App
  • At least one driver with driver.js, device.js, and driver.compose.json
  • /locales/en.json for any translated strings
  • README.txt

The app ID must be in reverse domain notation (e.g., com.example.mydevice). Never use "homey" or "athom" in the app ID.

Minimal app.js

'use strict';

const Homey = require('homey');

class MyApp extends Homey.App {
  async onInit() {
    this.log('MyApp has been initialized');
  }
}

module.exports = MyApp;

Minimal driver.js

'use strict';

const Homey = require('homey');

class MyDriver extends Homey.Driver {
  async onInit() {
    this.log('MyDriver has been initialized');
  }

  async onPairListDevices() {
    // Return an array of discovered devices
    return [];
  }
}

module.exports = MyDriver;

Minimal device.js

'use strict';

const Homey = require('homey');

class MyDevice extends Homey.Device {
  async onInit() {
    this.log('MyDevice has been initialized');

    // Register capability listeners
    this.registerCapabilityListener('onoff', async (value) => {
      // Handle the on/off command
      this.log('onoff changed to', value);
    });
  }

  async onAdded() {
    this.log('MyDevice has been added');
  }

  async onSettings({ oldSettings, newSettings, changedKeys }) {
    this.log('MyDevice settings changed');
  }

  async onDeleted() {
    this.log('MyDevice has been deleted');
  }
}

module.exports = MyDevice;

Minimal driver.compose.json

{
  "name": { "en": "My Device" },
  "class": "socket",
  "capabilities": ["onoff"],
  "platforms": ["local", "cloud"],
  "connectivity": ["cloud"],
  "pair": [
    {
      "id": "list_devices",
      "template": "list_devices",
      "navigation": { "next": "add_devices" }
    },
    {
      "id": "add_devices",
      "template": "add_devices"
    }
  ]
}

Critical Rules

  1. Never edit /app.json directly — it is generated by Homey Compose from *.compose.json files.
  2. Never overwrite constructors on App, Driver, or Device — use onInit() instead.
  3. Use this.homey.* for timers — call this.homey.setInterval() / this.homey.setTimeout() instead of the global versions, so timers are auto-cleared on app destroy (critical for Homey Cloud multi-tenancy).
  4. Device data must be immutable and unique — use MAC addresses or serial numbers, never IP addresses. Store changing properties in the device store or settings.
  5. Always handle promise rejections — unhandled rejections crash apps on Homey Cloud. Use .catch(this.error) for fire-and-forget promises.
  6. Access managers via this.homey — e.g., this.homey.flow, this.homey.settings, this.homey.drivers.
  7. App instance from Device/Driver: this.homey.app gives you the App instance.
  8. Environment variables: defined in /env.json, accessed as Homey.env.VARIABLE_NAME (uppercase, string values only).
  9. ESM support: Homey supports ES modules. See the ESM guide if using import/export syntax.

Homey Cloud Considerations

When targeting Homey Cloud ("platforms": ["local", "cloud"]):

  • No local Wi-Fi (no mDNS/SSDP/MAC discovery)
  • No App Web API (api.js)
  • No app-to-app communication
  • No homey:manager:api permission
  • Must handle multi-tenancy: no global state, use this.homey.* for timers
  • Apps run in Docker; homey app run requires Docker for cloud testing
  • Unhandled promise rejections will crash the app

Quick Reference: Common Patterns

Polling a Cloud API

async onInit() {
  this.pollInterval = this.homey.setInterval(() => {
    this.pollDevice().catch(this.error);
  }, 30000);
}

async onUninit() {
  this.homey.clearInterval(this.pollInterval);
}

Setting Capability Values (Device → Homey)

await this.setCapabilityValue('measure_temperature', 22.5);
// For custom boolean capabilities, this auto-triggers Flow cards

Listening for Capability Changes (Homey → Device)

this.registerCapabilityListener('target_temperature', async (value, opts) => {
  await this.api.setTemperature(value);
});

Firing a Flow Trigger

// In app.js onInit():
const myTrigger = this.homey.flow.getDeviceTriggerCard('my_event');
// Later, from a device:
await this.driver.myTrigger.trigger(this, { token_key: 'value' }, {});

Using Device Discovery (mDNS)

Read references/wireless-and-cloud.md for the full discovery pattern including onDiscoveryResult, onDiscoveryAvailable, and onDiscoveryAddressChanged.


For detailed documentation on any topic, read the relevant reference file listed above. The official documentation lives at https://apps.developer.homey.app/ and the SDK v3 API reference at https://apps-sdk-v3.developer.homey.app/.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

github-tools

Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.

Archived SourceRecently Updated
Coding

openclaw-version-monitor

监控 OpenClaw GitHub 版本更新,获取最新版本发布说明,翻译成中文, 并推送到 Telegram 和 Feishu。用于:(1) 定时检查版本更新 (2) 推送版本更新通知 (3) 生成中文版发布说明

Archived SourceRecently Updated
Coding

ask-claude

Delegate a task to Claude Code CLI and immediately report the result back in chat. Supports persistent sessions with full context memory. Safe execution: no data exfiltration, no external calls, file operations confined to workspace. Use when the user asks to run Claude, delegate a coding task, continue a previous Claude session, or any task benefiting from Claude Code's tools (file editing, code analysis, bash, etc.).

Archived SourceRecently Updated
Coding

ai-dating

This skill enables dating and matchmaking workflows. Use it when a user asks to make friends, find a partner, run matchmaking, or provide dating preferences/profile updates. The skill should execute `dating-cli` commands to complete profile setup, task creation/update, match checking, contact reveal, and review.

Archived SourceRecently Updated