Adbkit
A pure Node.js client for the Android Debug Bridge.
Install / Use
/learn @openstf/AdbkitREADME
adbkit
Warning
This project along with other ones in OpenSTF organisation is provided as is for community, without active development.
You can check any other forks that may be actively developed and offer new/different features here.
Active development has been moved to DeviceFarmer organisation.
Interested in helping to convert the CoffeeScript codebase to plain JavaScript? Help us!
adbkit is a pure [Node.js][nodejs] client for the [Android Debug Bridge][adb-site] server. It can be used either as a library in your own application, or simply as a convenient utility for playing with your device.
Most of the adb command line tool's functionality is supported (including pushing/pulling files, installing APKs and processing logs), with some added functionality such as being able to generate touch/key events and take screenshots. Some shims are provided for older devices, but we have not and will not test anything below Android 2.3.
Internally, we use this library to drive a multitude of Android devices from a variety of manufacturers, so we can say with a fairly high degree of confidence that it will most likely work with your device(s), too.
Requirements
- [Node.js][nodejs] >= 0.10
- The
adbcommand line tool
Please note that although it may happen at some point, this project is NOT an implementation of the ADB server. The target host (where the devices are connected) must still have ADB installed and either already running (e.g. via adb start-server) or available in $PATH. An attempt will be made to start the server locally via the aforementioned command if the initial connection fails. This is the only case where we fall back to the adb binary.
When targeting a remote host, starting the server is entirely your responsibility.
Alternatively, you may want to consider using the Chrome [ADB][chrome-adb] extension, as it includes the ADB server and can be started/stopped quite easily.
Getting started
Install via NPM:
npm install --save adbkit
We use [debug][node-debug], and our debug namespace is adb. Some of the dependencies may provide debug output of their own. To see the debug output, set the DEBUG environment variable. For example, run your program with DEBUG=adb:* node app.js.
Note that even though the module is written in [CoffeeScript][coffeescript], only the compiled JavaScript is published to [NPM][npm], which means that it can easily be used with pure JavaScript codebases, too.
Examples
The examples may be a bit verbose, but that's because we're trying to keep them as close to real-life code as possible, with flow control and error handling taken care of.
Checking for NFC support
var Promise = require('bluebird')
var adb = require('adbkit')
var client = adb.createClient()
client.listDevices()
.then(function(devices) {
return Promise.filter(devices, function(device) {
return client.getFeatures(device.id)
.then(function(features) {
return features['android.hardware.nfc']
})
})
})
.then(function(supportedDevices) {
console.log('The following devices support NFC:', supportedDevices)
})
.catch(function(err) {
console.error('Something went wrong:', err.stack)
})
Installing an APK
var Promise = require('bluebird')
var adb = require('adbkit')
var client = adb.createClient()
var apk = 'vendor/app.apk'
client.listDevices()
.then(function(devices) {
return Promise.map(devices, function(device) {
return client.install(device.id, apk)
})
})
.then(function() {
console.log('Installed %s on all connected devices', apk)
})
.catch(function(err) {
console.error('Something went wrong:', err.stack)
})
Tracking devices
var adb = require('adbkit')
var client = adb.createClient()
client.trackDevices()
.then(function(tracker) {
tracker.on('add', function(device) {
console.log('Device %s was plugged in', device.id)
})
tracker.on('remove', function(device) {
console.log('Device %s was unplugged', device.id)
})
tracker.on('end', function() {
console.log('Tracking stopped')
})
})
.catch(function(err) {
console.error('Something went wrong:', err.stack)
})
Pulling a file from all connected devices
var Promise = require('bluebird')
var fs = require('fs')
var adb = require('adbkit')
var client = adb.createClient()
client.listDevices()
.then(function(devices) {
return Promise.map(devices, function(device) {
return client.pull(device.id, '/system/build.prop')
.then(function(transfer) {
return new Promise(function(resolve, reject) {
var fn = '/tmp/' + device.id + '.build.prop'
transfer.on('progress', function(stats) {
console.log('[%s] Pulled %d bytes so far',
device.id,
stats.bytesTransferred)
})
transfer.on('end', function() {
console.log('[%s] Pull complete', device.id)
resolve(device.id)
})
transfer.on('error', reject)
transfer.pipe(fs.createWriteStream(fn))
})
})
})
})
.then(function() {
console.log('Done pulling /system/build.prop from all connected devices')
})
.catch(function(err) {
console.error('Something went wrong:', err.stack)
})
Pushing a file to all connected devices
var Promise = require('bluebird')
var adb = require('adbkit')
var client = adb.createClient()
client.listDevices()
.then(function(devices) {
return Promise.map(devices, function(device) {
return client.push(device.id, 'temp/foo.txt', '/data/local/tmp/foo.txt')
.then(function(transfer) {
return new Promise(function(resolve, reject) {
transfer.on('progress', function(stats) {
console.log('[%s] Pushed %d bytes so far',
device.id,
stats.bytesTransferred)
})
transfer.on('end', function() {
console.log('[%s] Push complete', device.id)
resolve()
})
transfer.on('error', reject)
})
})
})
})
.then(function() {
console.log('Done pushing foo.txt to all connected devices')
})
.catch(function(err) {
console.error('Something went wrong:', err.stack)
})
List files in a folder
var Promise = require('bluebird')
var adb = require('adbkit')
var client = adb.createClient()
client.listDevices()
.then(function(devices) {
return Promise.map(devices, function(device) {
return client.readdir(device.id, '/sdcard')
.then(function(files) {
// Synchronous, so we don't have to care about returning at the
// right time
files.forEach(function(file) {
if (file.isFile()) {
console.log('[%s] Found file "%s"', device.id, file.name)
}
})
})
})
})
.then(function() {
console.log('Done checking /sdcard files on connected devices')
})
.catch(function(err) {
console.error('Something went wrong:', err.stack)
})
API
ADB
adb.createClient([options])
Creates a client instance with the provided options. Note that this will not automatically establish a connection, it will only be done when necessary.
- options An object compatible with [Net.connect][net-connect]'s options:
- port The port where the ADB server is listening. Defaults to
5037. - host The host of the ADB server. Defaults to
'localhost'. - bin As the sole exception, this option provides the path to the
adbbinary, used for starting the server locally if initial connection fails. Defaults to'adb'.
- port The port where the ADB server is listening. Defaults to
- Returns: The client instance.
adb.util.parsePublicKey(androidKey[, callback])
Parses an Android-formatted mincrypt public key (e.g. ~/.android/adbkey.pub).
- androidKey The key String or [
Buffer][node-buffer] to parse. Not a filename. - callback(err, output) Optional. Use this or the returned
Promise.- err
nullwhen successful,Errorotherwise. - key The key as a forge.pki public key. You may need node-forge for complicated operations. Additionally the following properties are present:
- fingerprint The key fingerprint, like it would display on a device. Note that this is different than the one you'd get from
forge.ssh.getPublicKeyFingerprint(key), because the device fingerprint is based on the original format. - comment The key comment, if any.
- fingerprint The key fingerprint, like it would display on a device. Note that this is different than the one you'd get from
- err
- Returns:
Promise - Resolves with:
key(see callback)
adb.util.readAll(stream[, callback])
Takes a [Stream][node-stream] and reads everything it outputs until the stream ends. Then it resolves with the collected output. Convenient with client.shell().
- stream The [
Stream][node-stream] to read. - callback(err, output) Optional. Use this or the returned
Promise.- err
nullwhen successful,Errorotherwise. - output All the output as a [
Buffer][node-buffer]. Useoutput.toString('utf-8')to get a readable string from it.
- err
- Returns:
Promise - Resolves with:
output(see callback)
Client
client.clear(serial, pkg[, callback])
Deletes all data associated with a package from the device. This is roughly analogous to adb shell pm clear <pkg>.
- serial The serial number of the device. Corresponds to the device ID in
client.listDevices(). - pkg The package name. This is NOT the APK.
- callback(err) Optional. Use this or the returned
Promise.- err
nullwhen successful,Errorotherwise.
- err
- Retu
Related Skills
node-connect
346.4kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
107.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
346.4kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
346.4kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
