@mcesystems/apple-kit
v1.0.83
Published
iOS device management toolkit using libimobiledevice command-line tools
Maintainers
Readme
@mcesystems/apple-kit
iOS device management toolkit using libimobiledevice and go-ios command-line tools. We use both because they each provide capabilities that the other does not. The package provides app installation/uninstallation, port forwarding, activation, and device property access.
Features
- App Management: Install and uninstall iOS applications (.ipa files)
- Port Forwarding: Forward local ports to device ports (for debugging, etc.)
- Device Activation: Activate devices and skip setup steps
- Trust/Pairing: Handle device trust and pairing
- Device Info: Access device properties (name, model, iOS version, UDID, etc.)
- Profile Management: List and remove configuration profiles
- Device Wipe: Erase device data (factory reset)
- 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
- libimobiledevice tools (idevice*)
- go-ios
iosCLI binary
Platform-specific Requirements
Windows
- libimobiledevice binaries - use the export script (see below)
- go-ios
ios.exe(see Resources section below) - iTunes installed OR Apple Mobile Device Support
macOS
Option 1: Use bundled binaries (recommended for distribution)
Use the export script to bundle libimobiledevice 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
Resources and Binary Resolution
Set a resources directory once so both toolchains can be located:
import path from "node:path";
import { AppleDeviceKit } from "@mcesystems/apple-kit";
AppleDeviceKit.setResourcesDir(path.join(process.cwd(), "resources"));If you do not set a resources directory, make sure both toolchains are on your PATH.
The package looks for tools in this order:
resourcesDir/ios/bin/{platform}/(go-iosiosand libimobiledevice tools)- Homebrew paths on macOS (
/opt/homebrew/bin,/usr/local/bin) - System PATH (for global installations)
Usage
List Devices (go-ios)
import { createIosCli } from "@mcesystems/apple-kit";
// Example: <resourcesDir>/ios/bin/{platform}/ios(.exe)
const cli = createIosCli("path/to/ios");
const list = await cli.listDevices();
console.log(list.udids);Install/Uninstall Agent
import { AppleDeviceKit } from '@mcesystems/apple-kit';
const device = new AppleDeviceKit('device-udid', 1);
// Install app locally, then (if MDM is configured) take over management
await device.installApp('/path/to/agent.ipa', {
appId: 'com.example.agent',
url: 'https://example.com/agent.ipa',
waitForInstalled: true
});
// 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.info();
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.UniqueDeviceID}`);Trust/Pairing
const device = new AppleDeviceKit('device-udid', 1);
// Check if device is trusted
const isPaired = await device.isPaired();
// Trust the device (initiates pairing and waits for user acceptance)
await device.trustDevice(60000);
// Unpair device
await device.unpair();Port Forwarding
const device = new AppleDeviceKit('device-udid', 1);
// Forward device port 8080 to a local port (auto-allocated)
const forward = await device.startPortForwardAsync(8080);
console.log(`Local port: ${forward.localPort}`);
// Use the forwarded connection...
// connect to localhost:8080 to reach device:8080
// Stop forwarding when done
device.closePortForward();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 (uses go-ios and MDM client)
const cleanup = await device.activate();
if (cleanup) {
await cleanup(); // removes WiFi profile when done
}The activation flow can install a WiFi profile based on environment variables:
WIFI_SSID, WIFI_PASSWORD, WIFI_ENCRYPTION, WIFI_HIDDEN, WIFI_ENTERPRISE,
WIFI_USERNAME, and WIFI_EAP_TYPE.
Profiles
const device = new AppleDeviceKit('device-udid', 1);
// List profiles
const profiles = await device.listProfiles();
console.log(profiles.profiles);
// Remove a profile by identifier
await device.removeProfile("com.example.profile");Wipe Device
const device = new AppleDeviceKit('device-udid', 1);
// WARNING: this erases all data
await device.wipe();API Reference
AppleDeviceKit
Static methods:
setResourcesDir(dir): Configure resources location
Device Info:
info(): Get device propertiesgetDeviceId(): Get the device UDIDgetLogicalPort(): Get the logical port numbergetDevicePort(): Get current local forwarded port (or null)
App Management:
installApp(ipaPath, options): Install IPA and take over via MDM if configureduninstallApp(bundleId): Uninstall an app by bundle IDisAppInstalled(bundleId): Check if app is installedlistApps(): List all installed user apps
Trust/Pairing:
isPaired(): Check if device is paired/trustedpair(): Initiate pairing (user must accept on device)trustDevice(timeout?, onWaiting?): Pair and wait for user acceptanceunpair(): Remove pairing/trustwaitForPairing(timeout?, pollInterval?): Wait for device to be paired
Port Forwarding:
startPortForwardAsync(devicePort, startupTimeout?): Start and wait for readyclosePortForward(): Stop forwarding
Profiles:
listProfiles(): List installed profilesremoveProfile(identifier): Remove profile by identifier
Activation:
getActivationState(): Get activation stateactivate(): Activate the device (returns cleanup function)
Device Wipe:
wipe(): Erase device data
Lifecycle:
dispose(): Clean up resources and port forwards
Types
interface ActivationState {
isActivated: boolean;
activationState: string;
}License
ISC
libimobiledevice is licensed under LGPL-2.1.
