npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mcesystems/apple-kit

v1.0.83

Published

iOS device management toolkit using libimobiledevice command-line tools

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-kit

Requirements

  • Node.js 18+
  • iOS device connected via USB
  • Device must be trusted/paired with the computer
  • libimobiledevice tools (idevice*)
  • go-ios ios CLI 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/resources

See 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/bin or /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:

  1. resourcesDir/ios/bin/{platform}/ (go-ios ios and libimobiledevice tools)
  2. Homebrew paths on macOS (/opt/homebrew/bin, /usr/local/bin)
  3. 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 properties
  • getDeviceId(): Get the device UDID
  • getLogicalPort(): Get the logical port number
  • getDevicePort(): Get current local forwarded port (or null)

App Management:

  • installApp(ipaPath, options): Install IPA and take over via MDM if configured
  • uninstallApp(bundleId): Uninstall an app by bundle ID
  • isAppInstalled(bundleId): Check if app is installed
  • listApps(): List all installed user apps

Trust/Pairing:

  • isPaired(): Check if device is paired/trusted
  • pair(): Initiate pairing (user must accept on device)
  • trustDevice(timeout?, onWaiting?): Pair and wait for user acceptance
  • unpair(): Remove pairing/trust
  • waitForPairing(timeout?, pollInterval?): Wait for device to be paired

Port Forwarding:

  • startPortForwardAsync(devicePort, startupTimeout?): Start and wait for ready
  • closePortForward(): Stop forwarding

Profiles:

  • listProfiles(): List installed profiles
  • removeProfile(identifier): Remove profile by identifier

Activation:

  • getActivationState(): Get activation state
  • activate(): 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.