VPhone-CLI VM Configuration File (config.plist) Structure Explained

The vphone-cli VM configuration file is a Property List (config.plist) that maps directly to the Swift Codable struct VPhoneVirtualMachineManifest, defining hardware allocation, storage paths, network ports, and kernel boot arguments for virtual iPhone instances.

The vphone-cli tool orchestrates virtual iPhone instances using a single plist file to persist VM specifications. Understanding the config.plist structure is essential for customizing CPU allocation, memory size, disk images, and guest networking. This guide documents the exact key-value schema defined in the project source code and utilized during VM initialization.

Top-Level Configuration Keys

The root dictionary of config.plist corresponds to the VPhoneVirtualMachineManifest struct defined in sources/VPhoneCore/VPhoneVirtualMachineManifest.swift. Each top-level key accepts specific value types that translate directly to Swift properties.

Machine Identity and Hardware Resources

These keys define the virtual hardware profile presented to the guest operating system:

  • machineIdentifier (String): A stable identifier derived from the device ECID. Generated on first boot and persisted to ensure the guest maintains the same identity across restarts.
  • cpuCount (Int): Number of virtual CPU cores allocated to the VM. The default configuration assigns 2 cores.
  • memorySizeGB (Int): RAM allocation in gigabytes. Default values typically specify 4 GB.
  • hardwareModel (String): The hardware model string passed to the Private API Dynamic layer (e.g., iPhone14,2).

Boot Configuration and Extensions

Additional parameters control the kernel startup behavior and future-proofing:

  • bootArgs ([String]): An array of kernel boot arguments passed directly to the XNU kernel, such as ["-v", "debug=0x1"] for verbose boot.
  • additionalOptions ([String: Any]?): An optional dictionary reserved for extension flags, such as GPU passthrough or experimental features.

Storage Configuration Structure

The storage key contains a nested dictionary mapping to the Storage sub-struct. This specifies the virtual disk attachment.

  • diskImagePath (String): Absolute filesystem path to the .img file mounted as the VM's primary disk.
  • diskSizeGB (Int): Virtual disk capacity in gigabytes, utilized when the VPhoneCreateOrchestrator generates the initial disk image.

Network Configuration Structure

The network key maps to the Network sub-struct, configuring the vsock communication channel between host and guest.

  • vsockPort (UInt16): The port number for host-to-guest communication. The standard configuration uses 1337 for the VPhoneControl daemon connection.
  • bridgeEnabled (Bool): Flag indicating whether a host-to-guest network bridge is active, enabling external network access for the VM.

Source Code Implementation and File I/O

The vphone-cli codebase implements strict read/write patterns for the manifest file to ensure configuration persistence.

As implemented in VPhoneCreateOrchestrator.swift at line 361, the orchestrator serializes a new VPhoneVirtualMachineManifest instance to config.plist using PropertyListEncoder immediately after VM creation. During subsequent launches, VPhoneVirtualMachine.swift (lines 79-103) decodes the file using PropertyListDecoder to reconstruct the configuration object. The CLI entry point in VPhoneCLI.swift (line 32) accepts a --config argument to specify custom plist paths, loading the manifest before initializing the VZVirtualMachineConfiguration.

Practical Configuration Examples

Generating config.plist with Python

The repository includes a helper script at scripts/vm_manifest.py that programmatically assembles valid configuration files.

import plistlib
from pathlib import Path

def create_vm_config(vm_dir: Path):
    manifest = {
        "machineIdentifier": "00112233AABBCCDD",
        "cpuCount": 2,
        "memorySizeGB": 4,
        "hardwareModel": "iPhone14,2",
        "bootArgs": ["-v"],
        "storage": {
            "diskImagePath": str(vm_dir / "Disk.img"),
            "diskSizeGB": 64,
        },
        "network": {
            "vsockPort": 1337,
            "bridgeEnabled": False,
        },
    }
    config_path = vm_dir / "config.plist"
    config_path.write_bytes(plistlib.dumps(manifest))

Loading the Manifest in Swift

The core library uses standard Codable protocols to deserialize the plist at runtime.

import Foundation

func loadManifest(from url: URL) throws -> VPhoneVirtualMachineManifest {
    let data = try Data(contentsOf: url)
    let decoder = PropertyListDecoder()
    return try decoder.decode(VPhoneVirtualMachineManifest.self, from: data)
}

Applying Configuration to the Virtual Machine

After decoding, the manifest populates the VZVirtualMachineConfiguration object.

let manifest = try loadManifest(from: bundleURL.appendingPathComponent("config.plist"))
let config = VZVirtualMachineConfiguration()
config.cpuCount = manifest.cpuCount
config.memorySize = UInt64(manifest.memorySizeGB) * 1024 * 1024 * 1024
// Configure storage and network attachments using manifest.storage and manifest.network

Summary

  • The config.plist file maps directly to the VPhoneVirtualMachineManifest struct, conforming to Swift's Codable protocol.
  • Top-level keys include machineIdentifier, cpuCount, memorySizeGB, hardwareModel, bootArgs, storage, network, and additionalOptions.
  • The storage dictionary specifies diskImagePath and diskSizeGB for the primary disk attachment.
  • The network dictionary configures vsockPort (typically 1337) and bridgeEnabled status.
  • VPhoneCreateOrchestrator.swift writes the manifest at creation time, while VPhoneVirtualMachine.swift reloads it during boot.

Frequently Asked Questions

What format does vphone-cli use for the VM configuration file?

The configuration file uses Apple's Property List (plist) format, an XML or binary serialization format native to macOS and iOS development. According to the source code in VPhoneVirtualMachineManifest.swift, the file decodes into a Swift struct using PropertyListDecoder, making it compatible with standard macOS plist editing tools and Xcode's property list editor.

How do I specify a custom config.plist when launching a VM?

Use the --config command-line option provided by the CLI entry point in VPhoneCLI.swift. Pass the absolute or relative path to your plist file as the argument value. The orchestrator loads this file instead of the default bundle configuration, allowing multiple VMs with distinct hardware profiles to run from separate directories.

Can I manually edit the config.plist after creating a VM?

Yes, the plist is a text-based XML file (unless converted to binary) that can be edited with any text editor or plist editor. Modifications to values like cpuCount, memorySizeGB, or bootArgs take effect on the next VM launch, as VPhoneVirtualMachine.swift re-reads the file at lines 79-103 during the initialization sequence. Ensure valid data types match the Swift struct definitions to avoid decoding errors.

What happens if the machineIdentifier field is missing or changed?

The machineIdentifier field provides stable identity for the guest system. If removed or altered, the virtual iPhone will regenerate identifiers on next boot, potentially triggering re-activation flows or changing license validations within the guest OS. The VPhoneCreateOrchestrator.swift generates this value from the ECID during initial setup and persists it specifically to prevent identity drift across reboots.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →