<!--
{
  "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.
1. Set up a compatible VM configuration.
1. 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 ``doc://com.apple.virtualization/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 ``doc://com.apple.virtualization/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 ``doc://com.apple.virtualization/documentation/Virtualization/VZMacPlatformConfiguration``.
1. Set its `VZMacPlatformConfiguration`.``doc://com.apple.virtualization/documentation/Virtualization/VZMacPlatformConfiguration/hardwareModel`` to the `VZMacOSConfigurationRequirements`.``doc://com.apple.virtualization/documentation/Virtualization/VZMacOSConfigurationRequirements/hardwareModel``.
1. Create a new ``doc://com.apple.virtualization/documentation/Virtualization/VZMacAuxiliaryStorage`` with ``doc://com.apple.virtualization/documentation/Virtualization/VZMacAuxiliaryStorage/init(creatingStorageAt:hardwareModel:options:)`` using the `VZMacOSConfigurationRequirements`.``doc://com.apple.virtualization/documentation/Virtualization/VZMacPlatformConfiguration/hardwareModel``.
1. Set the new ``doc://com.apple.virtualization/documentation/Virtualization/VZMacAuxiliaryStorage`` on `VZMacPlatformConfiguration`.``doc://com.apple.virtualization/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 ``doc://com.apple.virtualization/documentation/Virtualization/VZVirtualMachineConfiguration`` with a ``doc://com.apple.virtualization/documentation/Virtualization/VZMacPlatformConfiguration`` configured as described above.
1. Create a new ``doc://com.apple.virtualization/documentation/Virtualization/VZVirtualMachine`` from the ``doc://com.apple.virtualization/documentation/Virtualization/VZVirtualMachineConfiguration``.
1. Create a ``doc://com.apple.virtualization/documentation/Virtualization/VZMacOSInstaller`` with the ``doc://com.apple.virtualization/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.
1. Call the installer’s ``doc://com.apple.virtualization/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:

```objc
// Load the latest image.
[VZMacOSRestoreImage fetchLatestSupportedWithCompletionHandler:^(VZMacOSRestoreImage *restoreImage, NSError *error) {
    if (error) {
        [NSException raise:NSGenericException format:@"No restore image is supported."];
    }
    downloadAndInstallRestoreImage(restoreImage);
}];

void downloadAndInstallRestoreImage(VZMacOSRestoreImage *restoreImage) {
    // Since restoreImage came from latestSupported, its URL property 
    //refers to a restore image on the network.
    // Download the restore image to the local filesystem.
    [[NSURLSession sharedSession] downloadTaskWithURL:restoreImage.URL completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
        if (error) {
            [NSException raise:NSGenericException format:
               @"Failed to download the restore image from the network."];
        }

        // VZMacOSInstaller must be called with a URL that corresponds to a 
        // local file.
        NSURL *localRestoreImageDirectoryURL = [NSURL fileURLWithPath:
              @"*set to the directory where the restore image should be stored*"];
        NSURL *localRestoreImageURL = [localRestoreImageDirectoryURL URLByAppendingPathComponent:restoreImage.URL.lastPathComponent];

        if (![[NSFileManager defaultManager] moveItemAtURL:location 
        toURL:localRestoreImageURL error:nil]) {
            [NSException raise:NSGenericException format:@"Failed to move the restore image to its destination."];
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            installLocalRestoreImage(restoreImage, localRestoreImageURL);
        });
    }];
}

void installLocalRestoreImage(VZMacOSRestoreImage *remoteRestoreImage, 
        NSURL *localRestoreImageURL) {
    // Since this restore image came from -[VZMacOSRestoreImage 
    // fetchLatestSupportedWithCompletionHandler:], 
    // mostFeaturefulSupportedConfiguration should not be nil.
    VZMacOSConfigurationRequirements *configurationRequirements = remoteRestoreImage.mostFeaturefulSupportedConfiguration;

    // Construct a VZVirtualMachineConfiguration that satisfies the configuration requirements.
    VZVirtualMachineConfiguration *configuration = [[VZVirtualMachineConfiguration alloc] init];

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

    configuration.bootLoader = [[VZMacOSBootLoader alloc] init];

    // Set up a valid Mac platform configuration for the restore image.
    VZMacHardwareModel *hardwareModel = configurationRequirements.hardwareModel;
    VZMacPlatformConfiguration *macPlatformConfiguration = [[VZMacPlatformConfiguration alloc] init];
    NSURL *auxiliaryStorageURL = [NSURL fileURLWithPath:@"*set to the path where "
                                  "the auxiliary storage should be stored*"];
    VZMacAuxiliaryStorage *auxiliaryStorage = [[VZMacAuxiliaryStorage alloc] initCreatingStorageAtURL:auxiliaryStorageURL
                                                                                        hardwareModel:hardwareModel
                                                                                              options:0
                                                                                                error:nil];
    if (auxiliaryStorage == nil) {
        [NSException raise:NSGenericException format:
        @"Failed to create auxiliary storage."];
    }
    macPlatformConfiguration.auxiliaryStorage = auxiliaryStorage;
    macPlatformConfiguration.hardwareModel = hardwareModel;
    configuration.platform = macPlatformConfiguration;

    // Set other configuration properties as necessary.
    [NSException raise:NSGenericException format:@"*set up storageDevices,"
        " graphicsDevices, pointingDevices, keyboards, etc. here*"];

    assert([configuration validateWithError:nil]);

    VZVirtualMachine *virtualMachine = [[VZVirtualMachine alloc] initWithConfiguration:configuration];
    VZMacOSInstaller *installer = [[VZMacOSInstaller alloc] initWithVirtualMachine:virtualMachine restoreImageURL:localRestoreImageURL];
    [installer installWithCompletionHandler:^(NSError *error) {
        if (error) {
            [NSException raise:NSGenericException format:@"Installation failure: %@", error];
        } else {
            // Installation was successful.
        }
    }];

    // Observe progress using installer.progress object.
    [installer.progress addObserver:observer forKeyPath:@"fractionCompleted" 
        options:NSKeyValueObservingOptionInitial | 
        NSKeyValueObservingOptionNew context:nil];
}
```

---

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)
