Skip to content

Latest commit

Β 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

DroidSock

DroidSock Banner

A complete, from-scratch implementation of the Android Debug Bridge (ADB) protocol in Node.js. This library provides full ADB functionality including device connection, RSA authentication, shell command execution, and file transfers - eliminating clicking sounds on Android TV devices!

npm version npm downloads GitHub downloads Last commit npm last update coverage

Contributors Sponsor shinrai

Note

Current status:

  • Shell + streaming: Stable - command execution, interactive shells, and log/process streaming all work over the real ADB protocol.
  • File transfer: mkdir / remove / move / copy / chmod / diskUsage / find / stat work today via shell commands. list prefers a binary-safe SYNC-based implementation with automatic shell fallback.
  • Experimental: push / pull / pushV2 / pullV2 / listSync / listV2 / statV2 (real ADB SYNC sub-protocol usage, both the legacy 32-bit and newer 64-bit variants), device.reboot(), device.forward() / device.reverse(), device.install() (both the classic push-then-install and modern streaming install paths), and pairing.pair() (Wi-Fi pairing) are all implemented - built from the ADB protocol spec and covered by unit tests (several exercised against real loopback TCP/TLS servers, not purely mocks) - but none of them have been run against a real device yet. See #1.

✨ What's New

Latest: v2.0.0 (September 2026)

  • 🚨 Breaking: the device module is now split into device (single-target connect(host, port) / disconnect(host, port) / remove(host, port)) and devices (collection-wide list() / disconnect() (all) / remove() (all) / get(idOrLeaf)) - connected devices are still mounted as composed API leaves at api.devices.<host_port>. A device leaf now persists across a disconnect - disconnect() only tears down the socket (and stays synchronous), connect() on the same host:port later reconnects that same leaf without re-supplying options, and remove() is the new, separate "forget this device" operation (the one that's actually async).
  • IPv6 support - device.connect(), discover.subnet(), and discover.mdns() all accept IPv6 addresses/CIDRs now, not just IPv4.
  • devices.get(idOrLeaf) (new) - looks up a connected device leaf by "host:port" string or by the leaf object itself; the safe way to re-resolve a leaf reference instead of holding onto a stale one.
  • device.reverse() (experimental) - completes port forwarding with the device β†’ host direction.
  • pairing.pair() (experimental) - Wi-Fi pairing (SPAKE2-over-Ed25519 + TLS 1.3) for Android 11+ wireless debugging.
  • Streaming APK install (experimental) - device.install() now tries exec:cmd-based streaming install first, falling back to the classic push-then-install flow.
  • SYNC V2 (64-bit) - pushV2 / pullV2 / statV2 / listV2 lift the legacy 32-bit size ceiling, with optional brotli compression.
  • Hardening - closed a shell-injection gap in devices.mjs's and shell.mjs's convenience shortcuts, capped several unbounded device-controlled memory allocations in the SYNC V2 paths, and fixed a handful of mid-transfer disconnect/failure edge cases.
  • View full v2.0.0 Changelog

Recent Releases

  • v1.2.0 (September 2026) - Device discovery (discover.subnet() CIDR sweep, discover.mdns() for wireless-debugging-advertised devices, both experimental) and a shell-injection fix across every files.* shell-based method (Changelog)
  • v1.1.1 (September 2026) - Documentation formatting fix (padded slashes between adjacent code spans) - no code changes (PR #16)
  • v1.1.0 (September 2026) - Fixed the list()/stat() regression from v1.0.0, and added a binary-safe SYNC-based list() with shell fallback, real ADB reboot: support, TCP port forwarding, and local APK install (Changelog)
  • v1.0.0 (September 2026) - First tagged release - a callable quick-path default export (dropping connect()/listDevices()), a real test suite with measured coverage, and a full CI/release pipeline (Changelog)

πŸ“š For complete version history and detailed release notes, see docs/changelog/ folder.


πŸš€ Key Features

  • βœ… Complete ADB Protocol: TCP connection, CNXN/AUTH handshake, and stream multiplexing implemented from scratch
  • βœ… RSA Authentication: Automatic key generation and ADB-specific signature/public-key formatting
  • βœ… Stream Multiplexing: Multiple concurrent operations over a single connection
  • βœ… Shell Commands: Execute commands, stream output, interactive sessions
  • βœ… File Operations: Shell-based mkdir / remove / move / copy / chmod / diskUsage / find, plus binary-safe SYNC-based list, and experimental push / pull (legacy 32-bit) / pushV2 / pullV2 / listV2 / statV2 (64-bit)
  • βœ… Reboot (experimental): Real reboot: service, including bootloader/recovery/sideload modes
  • βœ… Port Forwarding (experimental): adb forward/adb reverse-equivalent TCP tunneling, both directions
  • βœ… APK Install (experimental): adb install-equivalent local APK installation - classic push-then-install and modern streaming (exec:cmd package install) paths
  • βœ… Wi-Fi Pairing (experimental): adb pair-equivalent PIN-based pairing (SPAKE2-over-Ed25519 + TLS 1.3) for Android 11+ wireless debugging
  • βœ… Device Discovery: Support for multiple devices via configuration
  • βœ… Error Handling: Robust error handling and connection recovery

Installation

npm install @cldmv/droidsock

Quick Start

import droidsock from "@cldmv/droidsock";

// Create the API instance
const api = await droidsock();

// Connect to a device
const device = await api.device.connect("10.6.0.108", 5555);

// Execute a shell command
const output = await device.shell("ls -la");
console.log(output);

// Convenience getters
const model = await device.getModel();
const version = await device.getAndroidVersion();

// Stream commands
const logcat = device.logcat({
	onData: (data) => console.log(data)
});

// Clean up
await device.disconnect();

Device Configuration

Use the references/devices.json file to configure your devices:

{
	"livingroom": {
		"name": "Living Room TV",
		"host": "10.6.0.108",
		"port": 5555,
		"description": "Main living room Android TV"
	},
	"bedroom": {
		"name": "Master Bedroom TV",
		"host": "10.6.0.118",
		"port": 5555,
		"description": "Master bedroom Android TV"
	},
	"default": "livingroom"
}

API Reference

droidsock(options) (also createDroidSock) creates the API instance; api.device.connect(host, port, options) connects to a device (IPv4 or IPv6) and returns its live leaf - also reachable afterward at api.devices["<host>_<port>"] (a . becomes _, a : becomes __) - exposing connection state, shell execution/streaming, file operations (push / pull / list / stat), reboot, port forwarding, and APK install. api.device.disconnect(host, port) tears down one device's connection without forgetting it - reconnect later with connect() on the same host:port, no need to re-supply options; api.device.remove(host, port) forgets it entirely. api.devices.list() / disconnect() (all) / remove() (all) / get(idOrLeaf) manage the set of known devices as a whole.

πŸ“š See docs/API.md for the full method reference, including every option and the experimental/scope caveats on push / pull / list / forward / reverse / install.

Examples

Basic Usage

# Run basic example with default device
node examples/basic-usage.mjs

# Run with specific device
node examples/basic-usage.mjs livingroom

Streaming Commands

# Stream logcat
node examples/streaming-example.mjs logcat

# Stream top command
node examples/streaming-example.mjs top

# File transfer demo
node examples/streaming-example.mjs files

Architecture

src/droidsock.mjs composes the layers below into a single api tree via @cldmv/slothlet:

  1. Connection Layer (src/api/connection.mjs): TCP socket + CNXN/AUTH handshake
  2. Authentication Layer (src/api/auth.mjs): RSA key management and ADB signature/public-key formatting
  3. Stream Layer (src/api/stream.mjs): ADB stream multiplexing (OPEN/WRTE/OKAY/CLSE)
  4. Shell Layer (src/api/shell.mjs): Command execution, streaming, and interactive shell APIs
  5. Files Layer (src/api/files.mjs): Shell-based file operations, a binary-safe SYNC LIST implementation with automatic shell fallback, and an experimental ADB SYNC sub-protocol implementation for real binary transfer (push / pull) - not yet validated against a real device
  6. Reboot Layer (src/api/reboot.mjs): Real ADB reboot: service
  7. Forward Layer (src/api/forward.mjs): TCP port forwarding (host β†’ device) via the tcp: service
  8. Reverse Layer (src/api/reverse.mjs): TCP port forwarding (device β†’ host) via reverse:forward:/reverse:killforward: and the Stream layer's device-initiated stream handling
  9. Install Layer (src/api/install.mjs): Local APK install, composed from the Files and Shell layers
  10. Pairing Layer (src/api/pairing.mjs): Wi-Fi pairing (adb pair equivalent) - a separate TLS 1.3 + SPAKE2 protocol reusing the Authentication layer's persistent RSA identity, not composed with any of the layers above
  11. Device / Devices Layers (src/api/device.mjs, src/api/devices.mjs): High-level per-device API composing the layers above, split by single-target (device.connect/disconnect/remove) vs. collection-wide (devices.list/disconnect/remove/get) operations. Each device is a real, persistent slothlet leaf at api.devices.<sanitized host_port>, assigned there by connect() rather than held in a private module variable, so its methods keep working self/context access exactly like any other leaf - the leaf outlives any one connection, and only remove() unmounts it
  12. Config / Log Layers (src/api/config.mjs, src/api/log.mjs): Shared configuration and logging

πŸ“š See docs/PROTOCOL.md for wire-level protocol details (packet structure, auth flow, SYNC sub-protocol framing, reboot/forward service usage).

Troubleshooting

Connection Issues

  • Ensure device is on same network
  • Enable "ADB over network" in developer options
  • Check firewall settings
  • Verify IP address and port

Authentication Issues

  • Delete existing keys to force re-authorization: rm -rf ~/.adb
  • Ensure device shows authorization dialog
  • Check device storage permissions

Common Errors

  • "Command timeout": Increase timeout in options
  • "Stream not open": Ensure connection is established
  • "File not found": Check paths and permissions

Development

The implementation is built directly from the public ADB protocol documentation (AOSP SYNC.TXT and the wire-protocol references), cross-checked against Google's own reference client (google/python-adb) where the public docs are ambiguous, and covered by a mocked Vitest suite. The core connection/shell/stream-multiplexing path has real device usage behind it; the newer SYNC-protocol and service additions (push / pull / listSync / reboot / forward / install) have not yet been run against a real device - see the status note at the top of this README and #1.

License

Apache-2.0 - see LICENSE for details.

Contributing

This is a complete implementation of the ADB protocol. For improvements or bug fixes, please submit issues or pull requests.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages