ADB (Android Debug Bridge) toolkit for device management
npm install @mcesystems/adb-kitbash
npm install @mcesystems/adb-kit
`
Requirements: Node.js 18+, Android device with USB debugging enabled, and ADB binaries (see Resources).
3. Resources
This package needs ADB binaries to run. You can obtain them in one of these ways:
Option A – Export script (recommended for distribution)
Bundle ADB for your app using the provided script:
`bash
npx export-adb-resources /path/to/your-app/resources/adb-kit
All platforms
npx export-adb-resources /path/to/your-app/resources/adb-kit --all
`
See scripts/README.md for arguments, options, output layout, and prerequisites.
Option B – Development
- Windows / macOS: Set AdbBinPath to your ADB binary directory, or have adb on system PATH.
- Linux: Install via package manager (e.g. sudo apt install adb).
The package resolves ADB in this order: AdbBinPath env, then bundled resources under dist/resources/bin/, then system PATH.
4. Examples
Create a device kit and read properties
`typescript
import { AdbDeviceKit } from '@mcesystems/adb-kit';
const device = new AdbDeviceKit('device-serial-number', 1);
const [manufacturer, model] = await device.getDeviceProperties(['Manufacturer', 'Model']);
const allProps = await device.getAllDeviceProperties();
const devices = await device.listDevices();
`
Install/uninstall and check app
`typescript
await device.installApp('/path/to/app.apk');
const isInstalled = await device.isAppInstalled('com.example.app');
await device.uninstallApp('com.example.app');
`
USB debugging
`typescript
const hasDebugging = await device.hasUsbDebugging();
await device.waitForUsbDebugging(30000); // 30s timeout
`
Port forwarding
`typescript
const localPort = await device.startPortForward('tcp:8080');
`
Low-level clients
`typescript
const client = await device.getClient();
const deviceClient = await device.getDeviceClient();
`
First connected Android properties
One-shot example that discovers the first connected Android device and prints a curated set of its properties (manufacturer, model, brand, Android version, etc.).
`bash
From packages/adb-kit
pnpm example:first-android-properties
`
See src/examples/first-connected-android-properties.ts for the script.
USB debugging robustness example
Interactive example that runs the same flow 5 times to verify waitForUsbDebugging handling: start without USB debugging (device not found), short 5s timeout (user lets it pass), then wait up to 30s while the user enables USB debugging, show device recognized, then user disables USB debugging and repeats.
`bash
From packages/adb-kit (set ADB_DEVICE_SERIAL if USB debugging is off)
pnpm example:usb-debugging
`
See examples/usb-debugging-robustness.ts for the script.
For more scenarios and step-by-step explanations, see Example.md.
5. API
$3
Constructor
- Input: deviceId: string, port: number
- Output: new AdbDeviceKit instance bound to that device and logical port.
listDevices()
- Input: none
- Output: Promise — list of connected devices (AdbDevice: { id: string; type: AdbDeviceType }).
getDeviceProperties(properties)
- Input: properties: DeviceProperty[] — e.g. ['Manufacturer', 'Model']
- Output: Promise — values in the same order as properties; failed props are "".
getAllDeviceProperties()
- Input: none
- Output: Promise — all device properties from getprop.
installApp(appPath)
- Input: appPath: string — path to APK
- Output: Promise — resolves when install finishes; rejects on failure.
uninstallApp(packageName)
- Input: packageName: string — e.g. 'com.example.app'
- Output: Promise — resolves when uninstall finishes; rejects on failure.
isAppInstalled(packageName)
- Input: packageName: string
- Output: Promise — whether the package is installed.
hasUsbDebugging()
- Input: none
- Output: Promise — whether this device appears in the ADB device list.
waitForUsbDebugging(timeout?, numberOfAllowedAttempts?)
- Input: timeout?: number (default 120000 ms), numberOfAllowedAttempts?: number (default 5, accepted for backward compatibility; give-up is determined by timeout and tracker end only)
- Output: Promise — true when device is present and ready, false when tracking ends without device; rejects on timeout, device removal, or connection error.
startPortForward(serviceName)
- Input: serviceName: string — e.g. 'tcp:8080'
- Output: Promise — local port number used for forwarding, or null if forwarding failed. Reuses same port on repeated calls.
getClient()
- Input: none
- Output: Promise — underlying adbkit client.
getDeviceClient()
- Input: none
- Output: Promise — adbkit device client for this device.
getDeviceId()
- Input: none
- Output: string — device serial (last segment after \ on Windows).
getPort()
- Input: none
- Output: number — logical port passed to the constructor.
$3
Supported property names for getDeviceProperties():
Manufacturer, Name, Model, Brand, Device, Android Version, Platform, CPU, CPU.abi2, Description, Fingerprint, GSM Flexversion, GSM IMEI, Locale Language, Locale Region, Wifi Channels, Board Platform, Product Board, Display ID, Version Incremental, Version SDK, Version Codename, Version Release, Build Date, Build Type, Build User.
6. Flow
Example flow: wait for device, read identity, install an app, then forward a port.
`typescript
import { AdbDeviceKit } from '@mcesystems/adb-kit';
const deviceId = 'ABC123'; // from your device discovery
const device = new AdbDeviceKit(deviceId, 1);
// 1. Wait for USB debugging (e.g. after user enables it)
await device.waitForUsbDebugging(60000);
// 2. Identify device
const [manufacturer, model] = await device.getDeviceProperties(['Manufacturer', 'Model']);
console.log(Device: ${manufacturer} ${model});
// 3. Install app
await device.installApp('./build/app.apk');
// 4. Forward a device service to a local port
const localPort = await device.startPortForward('tcp:8080');
console.log(Service reachable at localhost:${localPort});
``