simctl - Xcode Simulator Utility Wrapper
The `simctl` library provides a Node.js-based programmatic interface for interacting with Apple's `simctl` command-line utility, which manages iOS Simulators on macOS. It enables developers to automate tasks such as listing available devices, booting simulators, installing and launching applications, and interacting with device settings directly from JavaScript or TypeScript code. The current stable version is 3.0.0, which introduced significant breaking changes related to output handling and method signatures. The project's release cadence is driven by updates to Xcode and internal improvements, rather than a fixed schedule. `simctl` is designed for Xcode 8 or greater and Node.js 14.17.0 or greater, acting as a foundational component for other iOS development tools like `ios-sim` by abstracting complex `xcrun simctl` commands into a more accessible API.
Common errors
-
TypeError: output.toString is not a function
cause Attempting to call `toString()` on a `Buffer` object, but `simctl` v3.0.0+ now returns strings directly, not Buffers.fixRemove `.toString()` calls from the output of `simctl` methods, as the output is already a UTF-8 string. -
Error: Command failed: xcrun simctl ... Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"
cause `xcrun simctl` command failed, often due to an incorrect path, missing Xcode components, or an Xcode version older than the required 8+.fixVerify Xcode is installed and up-to-date (Xcode 8+). Ensure `xcode-select --install` has been run for command line tools. Check if `xcrun simctl` works from the terminal. -
TypeError: simctl.spawn is not a function or signature mismatch
cause This error can occur if `spawn` is not correctly imported (e.g., using a default import instead of a named import) or if the arguments passed to `spawn` do not match its updated signature in `simctl` v3.0.0.fixEnsure `import { spawn } from 'simctl';` is used. Review the library's documentation for the correct `spawn` method signature in `simctl` v3.0.0+ and adjust your code accordingly.
Warnings
- breaking In `simctl` v3.0.0, all methods that call `spawnSync` now exclusively return UTF-8 encoded strings for `stdout`, `stderr`, and within `output`. Buffer output is no longer supported.
- breaking The `spawn` method signature was updated in `simctl` v3.0.0. Code using the old signature will break.
- breaking Starting with `simctl` v2.0.0, the `start` behavior changed: the simulator is now re-used if it has already been started, instead of being killed and restarted each time. This impacts workflows expecting a fresh simulator instance.
- gotcha `simctl` requires Xcode 8 or greater to be installed on macOS, and NodeJS 14.17.0 or greater.
Install
-
npm install simctl -
yarn add simctl -
pnpm add simctl
Imports
- list
const { list } = require('simctl');import { list } from 'simctl'; - spawn
const { spawn } = require('simctl');import { spawn } from 'simctl'; - simctl
import simctl from 'simctl';
import * as simctl from 'simctl';
Quickstart
import { list } from 'simctl';
async function getSimulatorInfo() {
console.log('Fetching available Simulators and runtimes...');
try {
const info = await list();
console.log('Devices:');
for (const runtimeId in info.devices) {
console.log(` Runtime: ${runtimeId}`);
info.devices[runtimeId].forEach(device => {
console.log(` - ${device.name} (${device.udid}) - ${device.state}`);
});
}
console.log('\nRuntimes:');
info.runtimes.forEach(runtime => {
console.log(` - ${runtime.name} (${runtime.identifier})`);
});
console.log('\nDevice Types:');
info.devicetypes.forEach(type => {
console.log(` - ${type.name} (${type.identifier})`);
});
} catch (error) {
console.error('Failed to retrieve simulator info:', error);
process.exit(1);
}
}
getSimulatorInfo();