<!--
{
  "documentType" : "article",
  "framework" : "Virtualization",
  "identifier" : "/documentation/Virtualization/installing-macos-on-a-virtual-machine",
  "metadataVersion" : "0.1.0",
  "role" : "article",
  "title" : "Installing macOS on a Virtual Machine"
}
-->

# Installing macOS on a Virtual Machine

Download a macOS restore image and install it in a new VM.

## Discussion

Each new VM begins in an empty state. To boot and run macOS in a VM, you must first install a macOS image onto the new VM. Installing macOS in a new machine requires the following steps:

1. Obtain a restore image.
2. Set up a compatible VM configuration.
3. Create a VM, install the restore image, and start the VM.

### Obtaining the Restore Image

A macOS restore image is an installation media file for a specific version of macOS. Use [`VZMacOSRestoreImage`](/documentation/Virtualization/VZMacOSRestoreImage) to find restore images over the network and obtain information about their requirements. To obtain a new restore image use the [`latestSupported`](/documentation/Virtualization/VZMacOSRestoreImage/latestSupported) class function to download the latest supported macOS image over from Apple the network using the URL in the restore image’s [`url`](/documentation/Virtualization/VZMacOSRestoreImage/url) property.

If you already have a restore image on disk, you can reload the [`VZMacOSRestoreImage`](/documentation/Virtualization/VZMacOSRestoreImage) from a local URL instead.

### Setting up the VM Configuration

Running a macOS, VM requires a valid [`VZMacPlatformConfiguration`](/documentation/Virtualization/VZMacPlatformConfiguration), a [`VZMacOSBootLoader`](/documentation/Virtualization/VZMacOSBootLoader), and a configuration compatible with the [`VZMacOSRestoreImage`](/documentation/Virtualization/VZMacOSRestoreImage).

A [`VZMacOSRestoreImage`](/documentation/Virtualization/VZMacOSRestoreImage) can contain installation media for multiple Mac hardware models ([`VZMacHardwareModel`](/documentation/Virtualization/VZMacHardwareModel)) and the current host may not support some of these hardware models. Use the [`mostFeaturefulSupportedConfiguration`](/documentation/Virtualization/VZMacOSRestoreImage/mostFeaturefulSupportedConfiguration) property to determine the hardware model and configuration requirements that provides the most complete feature set compatible with the current host. If the current hosts supports none of the hardware models, this property is `nil`.

The [`VZMacPlatformConfiguration`](/documentation/Virtualization/VZMacPlatformConfiguration) configuration encapsulates all the necessary unique components for booting and running macOS on Apple silicon, these are:

- The hardware model — A Mac platform configuration must describe the specific virtual Mac hardware model it targets. During installation this should match the `hardwareModel` of the [`VZMacOSRestoreImage`](/documentation/Virtualization/VZMacOSRestoreImage).
- Auxiliary storage — Auxiliary storage contains data used by the macOS boot loader and operating system and is necessary to boot a macOS guest OS. During installation this can be a newly created auxiliary image that uses the `hardwareModel` of the [`VZMacOSRestoreImage`](/documentation/Virtualization/VZMacOSRestoreImage).
- A machine identifier — A machine identifier that macOS guests use to uniquely identify the virtual hardware.

To configure the [`VZMacPlatformConfiguration`](/documentation/Virtualization/VZMacPlatformConfiguration) for installation:

1. Create a [`VZMacPlatformConfiguration`](/documentation/Virtualization/VZMacPlatformConfiguration).
2. Set its `VZMacPlatformConfiguration`.[`hardwareModel`](/documentation/Virtualization/VZMacPlatformConfiguration/hardwareModel) to the `VZMacOSConfigurationRequirements`.[`hardwareModel`](/documentation/Virtualization/VZMacOSConfigurationRequirements/hardwareModel).
3. Create a new [`VZMacAuxiliaryStorage`](/documentation/Virtualization/VZMacAuxiliaryStorage) with [`init(creatingStorageAt:hardwareModel:options:)`](/documentation/Virtualization/VZMacAuxiliaryStorage/init(creatingStorageAt:hardwareModel:options:)) using the `VZMacOSConfigurationRequirements`.[`hardwareModel`](/documentation/Virtualization/VZMacPlatformConfiguration/hardwareModel).
4. Set the new [`VZMacAuxiliaryStorage`](/documentation/Virtualization/VZMacAuxiliaryStorage) on `VZMacPlatformConfiguration`.[`auxiliaryStorage`](/documentation/Virtualization/VZMacPlatformConfiguration/auxiliaryStorage).

### Installing and Running the VM

Install a macOS using a [`VZMacOSInstaller`](/documentation/Virtualization/VZMacOSInstaller) with a VM instance and an image on the local filesystem using the following steps:

1. Create a [`VZVirtualMachineConfiguration`](/documentation/Virtualization/VZVirtualMachineConfiguration) with a [`VZMacPlatformConfiguration`](/documentation/Virtualization/VZMacPlatformConfiguration) configured as described above.
2. Create a new [`VZVirtualMachine`](/documentation/Virtualization/VZVirtualMachine) from the [`VZVirtualMachineConfiguration`](/documentation/Virtualization/VZVirtualMachineConfiguration).
3. Create a [`VZMacOSInstaller`](/documentation/Virtualization/VZMacOSInstaller) with the [`VZVirtualMachine`](/documentation/Virtualization/VZVirtualMachine) and the image that you downloaded, either as a new image from Apple servers or using a previously saved image. The URL must the refer to a local file on disk.
4. Call the installer’s [`install()`](/documentation/Virtualization/VZMacOSInstaller/install()) to start the installation.

A VM must be in a [`VZVirtualMachine.State.stopped`](/documentation/Virtualization/VZVirtualMachine/State-swift.enum/stopped) state to start installation. Pausing, or stopping the virtual machine during the installation process results in undefined behavior. You can monitor or cancel the installation progress by observing [`progress`](/documentation/Virtualization/VZMacOSInstaller/progress) property of the [`VZMacOSInstaller`](/documentation/Virtualization/VZMacOSInstaller).

The example below shows the complete process for installing and running a macOS VM:

```swift
    // Load the latest image.
    guard let restoreImage = try? await VZMacOSRestoreImage.latestSupported
    else {
        fatalError("No restore image is supported.")
    }

    // restoreImage came from latestSupported, its URL property refers
    // to an image on the network.
    // Download the image to the local filesystem.
    guard let (location, _) = try? await
            URLSession.shared.download(from: restoreImage.url) else {
                fatalError("""
                           Failed to download the macOS image from the network.
                           """)
    }

    // VZMacOSInstaller must be called with a URL corresponding to a local file.
    let localRestoreImageDirectoryURL =
    URL(fileURLWithPath: "*set to the directory where the restore image" 
        "should be stored*")
    let localRestoreImageURL = localRestoreImageDirectoryURL
        .appendingPathComponent(restoreImage.url.lastPathComponent)

    guard ((try? FileManager.default.moveItem(at: location, to:
                                                localRestoreImageURL)) != nil)
    else {
        fatalError("Failed to move the macOS image to its destination.")
    }

    // This image came from VZMacOSRestoreImage.latestSupported,
    // mostFeaturefulSupportedConfiguration should not be nil.
    let configurationRequirements =
        restoreImage.mostFeaturefulSupportedConfiguration!

    // Construct a VZVirtualMachineConfiguration that satisfies the
    // configuration requirements.
    let configuration = VZVirtualMachineConfiguration()

    // The following are minimum values; you can use larger values.
    configuration.cpuCount = configurationRequirements.minimumSupportedCPUCount
    configuration.memorySize =
        configurationRequirements.minimumSupportedMemorySize

    configuration.bootLoader = VZMacOSBootLoader()

    // Set up a valid Mac platform configuration for the restore image.
    let hardwareModel = configurationRequirements.hardwareModel
    let macPlatformConfiguration = VZMacPlatformConfiguration()
    let auxiliaryStorageURL = URL(fileURLWithPath:
        "*set to the path where the auxiliary storage should be stored*")
    guard let auxiliaryStorage = try? VZMacAuxiliaryStorage(creatingStorageAt:
                auxiliaryStorageURL,
                hardwareModel: hardwareModel,
                options: []) else {
                fatalError("Failed to create auxiliary storage.")
    }
    macPlatformConfiguration.auxiliaryStorage = auxiliaryStorage
    macPlatformConfiguration.hardwareModel = hardwareModel
    configuration.platform = macPlatformConfiguration

    fatalError(
        """
        *set up storageDevices, graphicsDevices, pointingDevices,
        keyboards, etc. here*
        """)

    guard ((try? configuration.validate()) != nil) else {
        fatalError("Virtual machine configuration is invalid.")
    }

    let virtualMachine = VZVirtualMachine(configuration: configuration)
    let installer = VZMacOSInstaller(virtualMachine: virtualMachine,
                                     restoringFromImageAt: localRestoreImageURL)
    installer.install(completionHandler: { (result: Result) in
        if case let .failure(error) = result {
            fatalError("Installation failure: \(error)")
        } else {
            // Installation was successful.
        }
    })

    // Observe progress using installer.progress object.
    installer.progress.observe(\.fractionCompleted, options: [.initial, .new]) {
        (progress, change) in
        print("Installation progress: \(change.newValue! * 100).")
    }

}
```

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)