TP-Link Smart Home API
This library provides a programmatic interface for controlling TP-Link Kasa smart home devices directly over the local network. It supports a wide range of devices including smart plugs (HS100, HS110, KP303), smart bulbs (LB100, KL125), and light strips (KL430), enabling local control without reliance on the TP-Link cloud services. The current stable version is 5.0.0, which targets Node.js environments version 16 and higher. While no explicit release cadence is documented, major version bumps suggest significant updates and potential breaking changes. A key differentiator is its focus on local LAN communication, offering increased privacy and potentially faster response times compared to cloud-dependent solutions. It ships with full TypeScript type definitions for an enhanced development experience, but importantly, does not support TP-Link Tapo devices.
Common errors
-
TypeError: (0 , tplink_smarthome_api_1.Client) is not a constructor
cause This typically occurs when trying to use CommonJS `require` syntax (`const { Client } = require(...)`) in an ES Module (`type: 'module'`) context, or vice-versa, without proper transpilation or configuration.fixIf using ES Modules (Node.js `--experimental-modules` or `"type": "module"` in `package.json`), use `import { Client } from 'tplink-smarthome-api';`. If using CommonJS, ensure you are using `const { Client } = require('tplink-smarthome-api');` and your `tsconfig.json` (if applicable) is set up for CJS output or `allowSyntheticDefaultImports: true`. -
Error: Device not found
cause The client could not reach the specified device IP or discover any devices. Common causes include incorrect IP, device being offline, network configuration issues (firewall, VLANs), or the device being a Tapo model.fixDouble-check the device IP address, ensure the device is powered on and connected to the network, verify your network settings allow UDP communication, and confirm it's a Kasa device, not Tapo. -
Tapo device not responding or unexpected behavior.
cause The `tplink-smarthome-api` library is specifically designed for TP-Link Kasa devices and does not support the Tapo line of products.fixThis library cannot control Tapo devices. You will need to find a different library or integration solution specifically for TP-Link Tapo products. -
ReferenceError: require is not defined
cause This error occurs when you attempt to use the `require()` function in a JavaScript file that is being interpreted as an ES Module (i.e., you have `"type": "module"` in your `package.json` or the file has a `.mjs` extension).fixChange your import statements from `const { Client } = require('tplink-smarthome-api');` to `import { Client } from 'tplink-smarthome-api';`. If you need to use `require` for other CJS modules, you might need to use a bundler or ensure your files are treated as CommonJS.
Warnings
- breaking Version 5.0.0 and newer requires Node.js version 16 or greater. Users on older Node.js runtimes will encounter errors and should upgrade their Node.js environment.
- gotcha TP-Link Tapo devices are explicitly NOT supported by this library. This API is designed for TP-Link Kasa devices (e.g., HS, KP, LB, KL series). Attempting to use it with Tapo devices will fail.
- gotcha TP-Link does not officially support or provide a public API for local control, meaning firmware updates to your Kasa devices could potentially break compatibility with this library at any time. Exercise caution when updating device firmware if local control is critical.
- gotcha Device discovery relies on UDP broadcast, which can be affected by network configuration (e.g., VLANs, router settings, firewalls). If devices aren't discovered, verify network settings or try specifying device IPs directly.
- breaking Major version 5.x.x includes significant internal refactoring and API changes. While core functionalities remain, some internal structures or less common API calls might have changed. Always consult the official changelog when upgrading from 4.x.x.
Install
-
npm install tplink-smarthome-api -
yarn add tplink-smarthome-api -
pnpm add tplink-smarthome-api
Imports
- Client
const { Client } = require('tplink-smarthome-api');import { Client } from 'tplink-smarthome-api'; - Device
import { Device } from 'tplink-smarthome-api';import type { Device } from 'tplink-smarthome-api'; - DimmableLight
import { DimmableLight } from 'tplink-smarthome-api';import type { DimmableLight } from 'tplink-smarthome-api';
Quickstart
import { Client } from 'tplink-smarthome-api';
const client = new Client();
const deviceIp = process.env.KASA_DEVICE_IP ?? '192.168.1.100'; // Replace with your device's IP
async function controlDevice() {
console.log(`Attempting to connect to device at ${deviceIp}...`);
try {
const device = await client.getDevice({ host: deviceIp });
const sysInfo = await device.getSysInfo();
console.log(`Connected to ${sysInfo.alias} (${sysInfo.model})`);
const initialState = await device.getPowerState();
console.log(`Current power state: ${initialState ? 'ON' : 'OFF'}`);
const newState = !initialState;
await device.setPowerState(newState);
console.log(`Set power state to: ${newState ? 'ON' : 'OFF'}`);
if (device.deviceType === 'bulb' && 'setBrightness' in device) {
const currentBrightness = await (device as any).getBrightness();
console.log(`Current brightness: ${currentBrightness}%`);
await (device as any).setBrightness(50);
console.log('Set brightness to 50%');
}
} catch (error) {
console.error('Error controlling device:', error instanceof Error ? error.message : error);
}
}
async function discoverDevices() {
console.log('Starting device discovery for 10 seconds...');
client.startDiscovery({ discoveryInterval: 1000, discoveryTimeout: 10000 });
client.on('device-new', async (device) => {
const sysInfo = await device.getSysInfo();
console.log(`[Discovery] Found new device: ${sysInfo.alias} (${sysInfo.host})`);
// Example: Turn on newly discovered smart plugs
if (device.deviceType === 'plug') {
await device.setPowerState(true);
console.log(`[Discovery] Turned on plug: ${sysInfo.alias}`);
}
});
client.on('device-online', (device) => console.log(`[Discovery] Device online: ${device.host}`));
client.on('device-offline', (device) => console.log(`[Discovery] Device offline: ${device.host}`));
setTimeout(() => {
client.stopDiscovery();
console.log('Discovery stopped.');
}, 10000);
}
// Run both examples
controlDevice();
discoverDevices();