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

@xsim/cli

v0.0.1

Published

Programmatic iOS simulator seeding CLI

Readme

XSim

XSim is a small Node.js CLI for building, seeding, and replaying iOS Simulator profiles from YAML.

It helps you:

  • scaffold a profile from an Xcode project or workspace
  • seed simulator state with files, media, permissions, location, push notifications, clipboard content, and app data
  • launch a fresh simulator from that profile
  • record new AXe launch steps back into the profile
  • clone a booted simulator into a reusable profile
  • tear down generated simulators when you are done

Requirements

  • macOS
  • Node.js 18 or newer
  • Xcode command line tools
  • xcodebuild and xcrun available on PATH
  • AXe available on PATH, or Homebrew so xsim init can install it for you
  • swift on PATH if you want to use xsim record

xsim init checks for AXe and installs it with Homebrew if it is missing.

Quick Start

Choose one of these two setup paths. Most people will use the default profile, so the examples below assume default unless noted otherwise.

Option 1: Install from npm

Install the package globally:

npm install -g @xsim/cli

Then verify the CLI is available:

xsim --help

From there, create a profile and launch it:

xsim init .
xsim launch

If you omit the profile name, default is used.

Option 2: Clone the repo locally

Use this path if you want to make changes and test them from your own checkout.

git clone <repo-url>
cd xsim-cli
npm install
npm run link

That makes the local xsim command available globally from this checkout.

To remove the global symlink later:

npm run unlink

Once linked, you can create and launch a profile the same way:

xsim init .
xsim launch

That will search upward and downward from the path you pass to find the Xcode project or workspace, detect a default scheme, and write a profile under .xsim/default/.

What XSim Creates

An initialized profile lives alongside your project:

your-project/
  .xsim/
    default/
      config.yml
      files/
      media/
      DerivedData/

Some commands may add more folders:

.xsim/
  default/
    appData/
    apps/

These are used when cloning simulators or restoring captured app data.

How It Works

At a high level, xsim launch does this:

  1. Finds the .xsim/<profile> directory.
  2. Reads config.yml.
  3. Resolves the Xcode project and scheme.
  4. Creates a new simulator with a generated display name like XSIM Default #ABCDE.
  5. Boots the simulator.
  6. Applies appearance, locale, location, and status bar overrides.
  7. Applies keychain, media, files, app data, permissions, clipboard, and push notification seed data.
  8. Builds the app from the detected scheme or installs a copied app bundle.
  9. Launches the app.
  10. Runs AXe launch steps, if any are configured.

The command prints the new simulator UUID on success.

Commands

xsim init <path> [name]

Creates a new profile for a project.

What it does:

  • discovers the Xcode project or workspace starting at <path>
  • resolves a default scheme with xcodebuild -list -json
  • creates .xsim/<name>/
  • writes config.yml
  • creates files/, media/, and DerivedData/

Options:

  • -f, --force overwrite an existing profile

Examples:

xsim init .
xsim init ~/Projects/MyApp staging
xsim init ~/Projects/MyApp staging --force

xsim launch [name]

Creates, seeds, and launches a simulator from a profile.

What it does:

  • finds .xsim/<name>
  • reads the profile config
  • creates a simulator using the configured or default device/runtime
  • applies all configured seed blocks
  • builds the app from the project scheme, or installs a cloned app bundle if the profile points to one
  • launches the app
  • runs any AXe batch steps in launchSteps

Options:

  • -q, --quiet suppress progress output and print only the simulator UUID

Examples:

xsim launch
xsim launch staging
xsim launch staging --quiet

xsim clone [name]

Clones a booted simulator into a new profile.

What it does:

  • prompts for a booted simulator if more than one is available
  • picks a running app when possible, otherwise a user app
  • tries to reuse an existing .xsim profile that matches the source simulator name
  • copies the source profile’s files/ and media/ folders when a matching profile exists
  • captures the selected app’s data container and app group containers into appData/
  • copies the app bundle into apps/ when no matching source profile exists
  • writes a new profile config

Options:

  • -q, --quiet suppress progress output

Examples:

xsim clone
xsim clone debug-profile

xsim record [name]

Launches a profile, then records new simulator interactions as AXe steps.

What it does:

  • locates the profile root
  • lets you choose a profile if one is not provided
  • boots a seeded simulator
  • starts a lightweight recorder that listens for mouse and keyboard events while the Simulator is frontmost
  • replays any existing launchSteps first
  • appends newly captured steps to config.yml

Options:

  • -q, --quiet suppress progress output

Notes:

  • you need swift installed
  • the terminal or shell must have Accessibility permissions so event capture can work

Example:

xsim record

xsim teardown [uuid]

Deletes simulator devices created by XSim.

What it does:

  • if you pass a UUID, it shuts down and deletes that simulator and removes its device directory
  • if you omit the UUID, it deletes every simulator whose name matches XSIM <profile> #ABCDE

Examples:

xsim teardown
xsim teardown 12345678-1234-1234-1234-123456789ABC

Profile Layout

The profile is just a directory with YAML and seed assets.

.xsim/<profile>/
  config.yml
  files/
  media/
  DerivedData/
  appData/
  apps/
  • config.yml controls simulator settings and seed behavior.
  • files/ is copied into the simulator’s iCloud Drive XSim/<profile>/ folder.
  • media/ is imported with simctl addmedia.
  • DerivedData/ is used as the build output directory.
  • appData/ stores captured app data snapshots for restore.
  • apps/ stores copied app bundles when cloning a simulator without an existing source profile.

Configuration Reference

config.yml is written in YAML and merged with a default schema.

Here is a simplified example:

version: 1
name: default
project:
  path: /absolute/path/to/MyApp.xcodeproj
  kind: xcodeproj
  root: /absolute/path/to
  scheme: MyApp
simulator:
  displayName: XSIM Default
  device: latest
  runtime: latest
  appearance: light
  locale: en_US
  language: en
permissions:
  photos: true
statusBar:
  time: "09:41"
  dataNetwork: wifi
  wifiMode: active
  batteryState: charged
  batteryLevel: 100
location:
  latitude: 37.3349
  longitude: -122.00902
keychain:
  reset: true
  rootCerts:
    - certs/root-ca.cer
pushNotifications:
  - bundleId: com.example.myapp
    payload:
      aps:
        alert:
          title: Hello
          body: Seeded push notification
clipboard:
  text: Hello from XSim
appData:
  - bundleId: com.example.myapp
    source: appData/com.example.myapp
launchSteps:
  steps:
    - tap --label "Continue"
    - sleep 1
    - type "Hello from XSim"
  options:
    waitTimeout: 2
    continueOnError: false

project

  • path points to the discovered .xcodeproj or .xcworkspace
  • kind is xcodeproj, xcworkspace, or app
  • root is the directory that contains the project bundle
  • scheme is the selected Xcode scheme

simulator

Supported fields include:

  • displayName
  • device
  • runtime
  • appearance
  • locale
  • language

The display name is turned into a real simulator name like XSIM Default #ABCDE.

permissions

Permissions are mapped to simctl privacy.

You can use:

  • true to grant
  • false to revoke
  • null to skip

Example:

permissions:
  camera: true
  photos: false

statusBar

statusBar is passed to simctl status_bar.

You can use direct overrides:

statusBar:
  time: "09:41"
  dataNetwork: wifi
  wifiMode: active
  batteryLevel: 100

You can also use:

statusBar:
  clear: true
  override:
    time: "12:00"

location

location is passed to simctl location.

Supported forms include:

location:
  latitude: 37.3349
  longitude: -122.00902
location:
  coordinate: "37.3349,-122.00902"
location:
  scenario: "gpx-route-name"

keychain

Controls simulator keychain seeding.

Supported fields:

  • reset
  • rootCerts
  • certs

Example:

keychain:
  reset: true
  rootCerts:
    - certs/root-ca.cer
  certs:
    - certs/client.cer

pushNotifications

Each entry can provide a bundle ID and either inline payload data or a file path.

Examples:

pushNotifications:
  - bundleId: com.example.myapp
    payload:
      aps:
        alert:
          title: Hello
          body: World
pushNotifications:
  - file: push/welcome.apns

clipboard

Sets the initial pasteboard contents.

Example:

clipboard:
  text: Hello from XSim

You can also use a plain string:

clipboard: Hello from XSim

appData

Two modes are supported:

  • point to a snapshot directory created by xsim clone
  • point to a .xcappdata package

Examples:

appData:
  - bundleId: com.example.myapp
    source: appData/com.example.myapp
appData:
  - path: snapshots/MyApp.xcappdata

launchSteps

Launch steps are run through AXe after the app launches.

You can provide:

  • steps: an array of inline AXe batch steps
  • file: a batch file path
  • options: additional AXe batch flags

Example:

launchSteps:
  steps:
    - tap --label "Continue"
    - sleep 1
    - type "hello"
  options:
    waitTimeout: 2
    continueOnError: false

Recorded steps are appended to the existing launchSteps.steps array.

Examples

Create a new profile

xsim init .

Launch it

xsim launch

Seed a different simulator size or runtime

simulator:
  device: iPhone 16 Pro
  runtime: latest

Add a root certificate and clipboard text

keychain:
  rootCerts:
    - certs/root-ca.cer
clipboard:
  text: "Logged in as [email protected]"

Seed a location and a push notification

location:
  latitude: 37.3349
  longitude: -122.00902
pushNotifications:
  - bundleId: com.example.myapp
    payload:
      aps:
        alert:
          title: Welcome
          body: Your profile is ready

Record a fresh flow

xsim record

Then interact with the app, press Enter in the terminal when finished, and the new AXe steps are appended to config.yml.

Notes and Limits

  • xsim launch expects a valid Xcode project, workspace, or app bundle path in the profile config.
  • xsim record only captures interactions while the Simulator is frontmost.
  • xsim clone and xsim teardown work against simulators managed by CoreSimulator.
  • If a configured path is relative, XSim resolves it relative to the profile directory.

Contributing

See CONTRIBUTING.md for development guidelines.

License

This project is licensed under the MIT License. See LICENSE.