Philips Hue API Library for Node.js
The `node-hue-api` library provides a comprehensive, Promise-based API for interacting with Philips Hue Bridges from Node.js applications. It abstracts the underlying Hue REST API, offering 100% coverage for both local network and remote internet access. The current stable major version is `v4`, with `v5.0.0-beta.16` actively in development, indicating a consistent update cadence through minor and patch releases. Key differentiators include its robust handling of self-signed bridge certificates for secure local connections, built-in rate limiting to comply with Hue API best practices (since v4.0.0), and full support for modern JavaScript `async/await` patterns. It offers complete control over lights, groups, scenes, sensors, schedules, and bridge configuration.
Common errors
-
Error: unable to get local issuer certificate
cause This error or similar certificate validation failures can occur when Node.js cannot properly validate the self-signed TLS certificate presented by the local Hue Bridge without the library's custom handling.fixEnsure you are using `createLocal(host).connect(username)` which includes the library's custom certificate validation logic. Avoid `https.Agent` configurations that might interfere. -
Error: 'username' not found, please ensure you have registered this username with the Hue Bridge.
cause The Hue Bridge requires a registered username (API key) for most API operations. This error typically means the provided username is invalid, not registered, or the bridge has been factory reset.fixIf this is the first connection or the username is lost, use the `createUser` method (e.g., `unauthenticatedApi.users.createUser(APP_NAME, DEVICE_NAME)`) to register a new user by pressing the button on the Hue Bridge. Store the generated username securely for future use. -
TypeError: Cannot read properties of undefined (reading 'lights')
cause This often happens if you try to use API methods (like `lights.getAll()`) on an API object that hasn't been properly connected or authenticated.fixEnsure that `createLocal(host).connect(username)` or `createRemote(clientId, clientSecret, accessToken).connect(username)` has successfully returned a connected `HueApi` instance before attempting to access its properties and methods.
Warnings
- breaking The v2 API, its shim, and associated modules were removed in v4.0.0. Projects upgrading from versions prior to v4 will need to update their code to use the v3 API exclusively.
- gotcha Since v4.0.0, the library introduces internal rate limiting to comply with Philips Hue API best practices, defaulting to 12 requests per second. While this prevents overloading the bridge from this library, other software on your network accessing the bridge might still cause issues.
- gotcha Connecting to the Hue Bridge over HTTP using `createInsecureLocal()` will output warnings. This method bypasses the library's custom TLS certificate validation and is primarily intended for use with emulated Hue Bridges, not official hardware.
- gotcha The package is currently in a `beta` release phase (v5.0.0-beta.x). While actively developed, beta versions may contain bugs, incomplete features, or further breaking changes before a stable v5 release. It is not recommended for production environments.
Install
-
npm install node-hue-api -
yarn add node-hue-api -
pnpm add node-hue-api
Imports
- HueApi
const HueApi = require('node-hue-api').HueApi;import { HueApi } from 'node-hue-api'; - discovery
const discovery = require('node-hue-api').discovery;import { discovery } from 'node-hue-api'; - LightState
import { LightState } from 'node-hue-api';import { LightState } from 'node-hue-api/thelper/LightState'; - api
const api = require('node-hue-api');import * as api from 'node-hue-api';
Quickstart
import { HueApi, discovery, LightState } from 'node-hue-api';
import { createLocal } from 'node-hue-api/dist/esm/api/Api';
const APP_NAME = 'my-node-hue-app';
const DEVICE_NAME = 'my-computer';
async function discoverAndConnect() {
let host;
try {
console.log('Searching for Hue Bridges...');
const discoveryResults = await discovery.upnpSearch(3000);
if (discoveryResults.length === 0) {
console.log('No bridges found via UPnP. Trying nUPnP...');
const nupnpResults = await discovery.nupnpSearch();
if (nupnpResults.length === 0) {
throw new Error('No Hue Bridges found on the network.');
}
host = nupnpResults[0].ipaddress;
} else {
host = discoveryResults[0].ipaddress;
}
console.log(`Found bridge at ${host}`);
const savedUsername = process.env.HUE_USERNAME ?? ''; // Or load from a config file
let username = savedUsername;
if (!username) {
console.log('No username found, registering new user...');
const unauthenticatedApi = createLocal(host).get.</unauthenticatedApi>
username = await unauthenticatedApi.users.createUser(APP_NAME, DEVICE_NAME);
console.log(`New user created: ${username}. Save this for future use.`);
} else {
console.log(`Using existing username: ${username}`);
}
const hueApi = createLocal(host).connect(username);
console.log('Successfully connected to the Hue Bridge.');
// Example: Set a light state
const lights = await hueApi.lights.getAll();
if (lights.length > 0) {
const firstLightId = lights[0].id;
console.log(`Setting first light (${lights[0].name}) to a random color and brightness.`);
const state = new LightState()
.on()
.brightness(50 + Math.floor(Math.random() * 50)) // 50-100%
.hue(Math.floor(Math.random() * 65535)); // Random hue
await hueApi.lights.setLightState(firstLightId, state);
console.log('Light state updated.');
} else {
console.log('No lights found to control.');
}
} catch (err) {
console.error(`Error during discovery or connection: ${err.message}`);
}
}
discoverAndConnect();