@mcesystems/apple-kit
v1.0.40
Published
iOS device management toolkit using libimobiledevice command-line tools
Maintainers
Readme
@mcesystems/apple-kit
iOS device management toolkit using libimobiledevice command-line tools. Provides device detection, app installation/uninstallation, port forwarding, activation, and device property access.
Features
- Device Detection: Monitor iOS device connections via USB plug-and-play
- App Management: Install and uninstall iOS applications (.ipa files)
- Launch Apps: Start applications on the device
- Port Forwarding: Forward local ports to device ports (for debugging, etc.)
- Device Activation: Check and manage device activation state
- Trust/Pairing: Handle device trust and pairing
- Device Info: Access device properties (name, model, iOS version, UDID, etc.)
- Cross-platform: Works on Windows, macOS, and Linux
Installation
npm install @mcesystems/apple-kitRequirements
- Node.js 18+
- iOS device connected via USB
- Device must be trusted/paired with the computer
Platform-specific Requirements
Windows
- libimobiledevice binaries - use the export script (see below)
- iTunes installed OR Apple Mobile Device Support
macOS
Option 1: Use bundled binaries (recommended for distribution)
Use the export script to bundle binaries for your application:
# Using npx (after installing the package)
npx export-apple-resources /path/to/your-app/resources/apple-kit
# Or run the script directly
npx tsx node_modules/@mcesystems/apple-kit/scripts/export-resources.ts /path/to/your-app/resourcesSee scripts/README.md for detailed prerequisites and instructions.
Option 2: Use Homebrew installation (for development)
- Install via Homebrew:
brew install libimobiledevice ideviceinstaller - Tools are auto-detected from
/opt/homebrew/bin(Apple Silicon) or/usr/local/bin(Intel)
Linux
- libimobiledevice-utils:
sudo apt install libimobiledevice-utils - Tools are auto-detected from
/usr/binor/usr/local/bin
Binary Resolution Order
The package looks for idevice tools in this order:
IDeviceBinPathenvironment variable (for custom paths)- Bundled resources in your app's
resources/bin/{platform}/directory - Homebrew paths on macOS (
/opt/homebrew/bin,/usr/local/bin) - System PATH (for global installations)
Usage
Device Monitoring
import { DevicesMonitor } from '@mcesystems/apple-kit';
const monitor = new DevicesMonitor({
logicalPortMap: {
"Port_#0005.Hub_#0002": 1,
"Port_#0006.Hub_#0002": 2
}
});
const events = await monitor.startTracking();
events.on('added', async (deviceKit) => {
console.log(`iOS device connected: ${deviceKit.getDeviceId()}`);
const info = await deviceKit.getDeviceInfo();
console.log(` ${info.deviceName} - iOS ${info.productVersion}`);
});
events.on('removed', (deviceId, port) => {
console.log(`iOS device disconnected: ${deviceId}`);
});
// Later: stop monitoring
await monitor.stopTracking();Install/Uninstall Agent
import { AppleDeviceKit } from '@mcesystems/apple-kit';
const device = new AppleDeviceKit('device-udid', 1);
// Install an agent/app
await device.installApp('/path/to/agent.ipa');
// Check if installed
const isInstalled = await device.isAppInstalled('com.example.agent');
// List all installed apps
const apps = await device.listApps();
// Uninstall an agent/app
await device.uninstallApp('com.example.agent');Device Info
const device = new AppleDeviceKit('device-udid', 1);
const info = await device.getDeviceInfo();
console.log(`Device: ${info.deviceName}`);
console.log(`Model: ${info.productType}`);
console.log(`iOS: ${info.productVersion} (${info.buildVersion})`);
console.log(`Serial: ${info.serialNumber}`);
console.log(`UDID: ${info.udid}`);Trust/Pairing
const device = new AppleDeviceKit('device-udid', 1);
// Check if device is trusted
const isPaired = await device.isPaired();
// Initiate pairing (user must accept on device)
await device.pair();
// Wait for user to accept trust dialog
await device.waitForPairing(60000); // 60 second timeout
// Unpair device
await device.unpair();Launch Application
const device = new AppleDeviceKit('device-udid', 1);
// Launch an app
await device.launchApp('com.example.myapp');
// Launch with arguments
await device.launchApp('com.example.myapp', ['--debug', '--port=8080']);Port Forwarding
const device = new AppleDeviceKit('device-udid', 1);
// Forward local port 8080 to device port 8080
const forward = device.startPortForward(8080, 8080);
// Use the forwarded connection...
// connect to localhost:8080 to reach device:8080
// Stop forwarding when done
forward.stop();
// Or use async version that waits for ready
const forwardAsync = await device.startPortForwardAsync(8080, 8080);Activation
const device = new AppleDeviceKit('device-udid', 1);
// Get activation state
const state = await device.getActivationState();
console.log(`Activated: ${state.isActivated}`);
console.log(`State: ${state.activationState}`);
// Activate device (requires valid activation record)
await device.activate();
// Deactivate device
await device.deactivate();Running Without iTunes (usbmuxd)
On Windows, iTunes provides the Apple Mobile Device Service for USB communication. If you don't have iTunes installed, you can run the bundled usbmuxd:
import { startUsbmuxd, stopUsbmuxd, ensureUsbmuxd } from '@mcesystems/apple-kit';
// Start usbmuxd daemon (required if iTunes is not installed)
const daemon = startUsbmuxd();
// Or ensure it's running (starts if not already running)
ensureUsbmuxd();
// Now you can use device operations...
const devices = await AppleDeviceKit.listDevices();
// When done, stop the daemon
stopUsbmuxd();
// or
daemon.stop();Note: The usbmuxd daemon must be running before connecting devices. Start it before plugging in your iOS device.
API Reference
AppleDeviceKit
Static methods:
listDevices(): Get all connected iOS devices
Device Info:
getDeviceInfo(): Get device propertiesgetDeviceId(): Get the device UDIDgetPort(): Get the logical port number
App Management:
installApp(ipaPath): Install an IPA fileuninstallApp(bundleId): Uninstall an app by bundle IDisAppInstalled(bundleId): Check if app is installedlistApps(): List all installed user appslaunchApp(bundleId, args?): Launch an application
Trust/Pairing:
isPaired(): Check if device is paired/trustedpair(): Initiate pairing (user must accept on device)unpair(): Remove pairing/trustwaitForPairing(timeout?): Wait for device to be paired
Port Forwarding:
startPortForward(localPort, devicePort): Start port forwardingstartPortForwardAsync(localPort, devicePort): Start and wait for ready
Activation:
getActivationState(): Get activation stateactivate(): Activate the devicedeactivate(): Deactivate the device
DevicesMonitor
startTracking(): Start monitoring for iOS device connectionsstopTracking(): Stop monitoringgetKits(): Get all currently tracked devicesgetKit(udid): Get a specific device kit by UDID
usbmuxd Functions
startUsbmuxd(foreground?): Start the usbmuxd daemonstopUsbmuxd(): Stop the daemonisUsbmuxdRunning(): Check if daemon is runningensureUsbmuxd(): Start if not already running
Types
interface PortForwardHandle {
stop: () => void;
localPort: number;
devicePort: number;
process: ChildProcess;
}
interface ActivationState {
isActivated: boolean;
activationState: string;
}License
ISC
libimobiledevice is licensed under LGPL-2.1.
