# How to Create a New VM Bundle with vphone-cli: A Complete Guide

> Learn to create a new VM bundle with vphone-cli. This guide covers using the vphone create command and understanding the generated configuration files for your virtual machine.

- Repository: [Lakr/vphone-cli](https://github.com/Lakr233/vphone-cli)
- Tags: how-to-guide
- Published: 2026-09-12

---

**Run `vphone create <bundle-name>` to generate a new VM bundle directory containing a `config.plist` manifest and optional disk image, orchestrated by `VPhoneCreateOrchestrator` in the Lakr233/vphone-cli source.**

The `vphone-cli` tool treats every virtual iPhone instance as a **VM bundle**—a self-contained directory with configuration and storage. When you create a new VM bundle with vphone-cli, the CLI generates the required manifest and directory structure using native Swift types defined in the `VPhoneCore` module.

## Understanding VM Bundle Structure

A VM bundle is a directory that encapsulates a virtual machine. According to the source code in [`sources/VPhoneCore/VPhoneBundle.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/VPhoneCore/VPhoneBundle.swift), each bundle contains:

- `config.plist`: The **VM manifest** (`VPhoneVirtualMachineManifest`) storing hardware model, boot arguments, and disk image references.
- Disk image: The raw storage file named by the manifest's `diskImage` property.

The `VPhoneBundle.load(at:)` method validates and loads these components at runtime, returning a fully initialized `VPhoneBundle` instance ready for boot operations.

## Creating a VM Bundle via CLI

The primary interface for creating bundles is the `vphone create` sub-command, implemented in [`sources/vphone-cli/VPhoneVMCreateCLI.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneVMCreateCLI.swift).

### Command Syntax and Options

```bash
vphone create <name> [options]

```

This command invokes **VPhoneCreateOrchestrator**, which performs three distinct operations:

1. **Directory creation**: Generates the bundle folder under the configured VM root path.
2. **Manifest serialization**: Writes a default `config.plist` using `VPhoneVirtualMachineManifest` codable structures.
3. **Disk preparation**: Optionally prepares a fresh disk image or copies a base template via routines in [`sources/VPhoneCore/VPhoneBundleOps.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/VPhoneCore/VPhoneBundleOps.swift).

### Creation Internals and Configuration

The orchestration logic leverages [`VPhoneBundleOps.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneBundleOps.swift) for atomic file system operations. During creation, the manifest is populated with default hardware parameters—such as the iPhone model identifier and boot arguments—that [`VPhoneVirtualMachine.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVirtualMachine.swift) later consumes when constructing the `VZVirtualMachineConfiguration` for the hypervisor.

## Programmatic Bundle Creation

You can also create bundles directly in Swift using the core library types without invoking the CLI:

```swift
import VPhoneCore

// Define the target bundle location
let vmRoot = URL(fileURLWithPath: "/Users/me/vphone/vms")
let bundleURL = vmRoot.appendingPathComponent("MyNewiPhone")

// Initialize the orchestrator
let orchestrator = VPhoneCreateOrchestrator()

// Create bundle with specific parameters
try orchestrator.create(
    at: bundleURL,
    hardwareModel: "iPhone14,2",
    diskSize: 64 * 1_024 * 1_024 * 1_024  // 64 GB in bytes
)

// Verify by loading the bundle
let bundle = try VPhoneBundle.load(at: bundleURL)
print("Created bundle: \(bundle.name)")
print("Disk size: \(bundle.diskSizeBytes / 1_048_576) MiB")

```

## Verifying and Managing New Bundles

After creation, validate the bundle using the inspect command:

```bash
vphone inspect MyNewiPhone

```

This prints metadata including the computed disk size via `VPhoneBundle.diskSizeBytes`, which lazily queries the file system for the actual image file. To view all available bundles, use `vphone list`, which relies on `VPhoneVMPicker` (defined in [`sources/VPhoneCore/VPhoneVMPicker.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/VPhoneCore/VPhoneVMPicker.swift)) to scan the VM root directory and filter for folders containing valid `config.plist` manifests.

## Summary

- **VM bundles** are directories containing `config.plist` and disk images, abstracted by the `VPhoneBundle` type in [`sources/VPhoneCore/VPhoneBundle.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/VPhoneCore/VPhoneBundle.swift).
- Use **`vphone create <name>`** to generate new bundles via the CLI implementation in [`VPhoneVMCreateCLI.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVMCreateCLI.swift).
- The **`VPhoneCreateOrchestrator`** handles directory creation, manifest serialization to `config.plist`, and optional disk image preparation.
- Verify creation with **`vphone inspect`** or programmatically via `VPhoneBundle.load(at:)`, which validates the manifest and computes storage metrics.

## Frequently Asked Questions

### What configuration format does vphone-cli use for VM bundles?

vphone-cli uses a **property list (`config.plist`)** to store VM configuration. The `VPhoneVirtualMachineManifest` struct in [`sources/VPhoneCore/VPhoneVirtualMachineManifest.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/VPhoneCore/VPhoneVirtualMachineManifest.swift) defines the schema, encoding hardware model identifiers, boot arguments, and disk image references using Swift's `Codable` protocol.

### Where does vphone-cli store newly created VM bundles?

Bundles are stored in the **VM root directory** configured at runtime. The `VPhoneVMPicker` class scans this root path for subdirectories containing `config.plist` files. When you run `vphone create`, the orchestrator writes the new bundle into this hierarchy, making it immediately discoverable by `vphone list`.

### Can I create a VM bundle without a disk image?

Yes. The `VPhoneCreateOrchestrator` logic in the creation workflow treats disk image preparation as **optional**. You can initialize an empty bundle with only the `config.plist` manifest, then attach or generate a disk image later using `VPhoneBundleOps` methods before booting via `vphone boot`.

### How do I safely delete a VM bundle I created?

Use **`vphone delete <name>`** to remove a bundle. This command triggers the deletion logic in [`sources/VPhoneCore/VPhoneBundleOps.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/VPhoneCore/VPhoneBundleOps.swift), which recursively removes the bundle directory and its associated disk image from the file system. This operation is irreversible and permanently deletes the virtual machine's storage.