# Purpose of the Main Entry Point File in Apple Container: A Developer Guide

> Discover the purpose of the main entry point file in the apple/container repository. Learn how ContainerCLI bootstraps the command-line interface, parses arguments, and delegates execution to sub-commands.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: developer-guide
- Published: 2026-07-06

---

**The main entry point file in the apple/container repository defines the `ContainerCLI` struct in [`Sources/CLI/ContainerCLI.swift`](https://github.com/apple/container/blob/main/Sources/CLI/ContainerCLI.swift), which bootstraps the command-line interface, parses arguments, validates the environment, and delegates execution to the appropriate sub-commands.**

The apple/container repository provides a Swift-based container platform. For developers working with this codebase, understanding the purpose of the main entry point file is essential for extending functionality or invoking the CLI programmatically. This entry point serves as the central coordination hub that bridges raw terminal arguments with the container runtime.

## Locating the Entry Point in Sources/CLI/ContainerCLI.swift

The primary entry point for developers is the **ContainerCLI** struct defined in [`Sources/CLI/ContainerCLI.swift`](https://github.com/apple/container/blob/main/Sources/CLI/ContainerCLI.swift). This file is annotated with `@main`, which instructs the Swift compiler that this struct contains the program's entry point.

### The @main Annotation and AsyncParsableCommand

By conforming to `AsyncParsableCommand` from Apple's ArgumentParser library, the `ContainerCLI` struct enables asynchronous command handling. The `@main` attribute ensures that building the project produces a single `container` executable binary. This design follows Swift Package Manager conventions for executable targets.

## Core Responsibilities of the Entry Point

The `ContainerCLI` struct fulfills four critical responsibilities that define the purpose of the main entry point file.

### Bootstrapping the CLI with ArgumentParser

The entry point initializes the command-line interface by leveraging ArgumentParser to declare global options and capture raw arguments. The struct configures the root command and delegates sub-command handling to the appropriate handlers. This bootstrap process occurs before any container-specific logic executes.

### Parsing and Validating Arguments

The `run()` method invokes `Application.parse(arguments)`, which constructs an `Application` value from [`Sources/ContainerCommands/Application.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Application.swift). Immediately after parsing, the code calls `application.validate()` to ensure the environment is appropriate—for example, verifying the process is not running under Rosetta—and to configure logging levels. This validation step prevents invalid states from reaching the container runtime.

### Launching the Core Runtime

After validation, `application.run()` executes the chosen sub-command (such as `container run` or `container image build`). The heavy lifting is performed by the `Application` type, which:

- Sets up signal handling and cursor restoration via `restoreCursorAtExit`
- Loads system configuration through `loadContainerSystemConfig`
- Dynamically discovers and loads plugins using `createPluginLoader`
- Delegates to the appropriate async or sync command implementation

### Providing a Single Executable Target

Because `ContainerCLI` is the only `@main` target in the project, building the package yields a single `container` binary. Developers can extend functionality by adding new sub-commands to `Application.configuration.subcommands` or by providing plugins that are discovered at runtime.

## Extending the CLI with Custom Commands

Developers can extend the entry point by adding custom sub-commands. The following example demonstrates how to create a new command and register it within the application configuration:

```swift
import ArgumentParser
import ContainerCommands

struct MyCustomCommand: AsyncParsableCommand {
    static let configuration = CommandConfiguration(
        commandName: "mycmd",
        abstract: "A custom developer command."
    )
    func run() async throws {
        print("Hello from my custom command!")
    }
}

// Register it in Application.configuration.subcommands
// (usually done in Application.swift under the appropriate CommandGroup)

```

## Key Source Files in the Entry Point Chain

Understanding the purpose of the main entry point file requires familiarity with related source files:

- **[`Sources/CLI/ContainerCLI.swift`](https://github.com/apple/container/blob/main/Sources/CLI/ContainerCLI.swift)** – The `@main` entry point that parses arguments and forwards to `Application`.
- **[`Sources/ContainerCommands/Application.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Application.swift)** – Core command infrastructure handling validation, plugin loading, signal handling, and sub-command dispatch.
- **`Sources/Plugins/`** – Implements the plugin system that `Application.createPluginLoader()` discovers at runtime.
- **`Sources/ContainerAPIClient/`** – Provides client-side API calls used by many commands for health checks and configuration loading.

## Programmatic Invocation

Developers can invoke the container CLI programmatically from other Swift tools. This is useful for building wrapper utilities or integration tests:

```swift
import ContainerCLI

@main
struct MyTool {
    static func main() async throws {
        // Forward any arguments to the built-in container CLI
        try await ContainerCLI.main()
    }
}

```

## Summary

- The main entry point file ([`Sources/CLI/ContainerCLI.swift`](https://github.com/apple/container/blob/main/Sources/CLI/ContainerCLI.swift)) defines the `ContainerCLI` struct annotated with `@main`.
- It bootstraps the CLI using ArgumentParser, parses arguments into an `Application` instance, and validates the environment.
- The entry point delegates actual execution to `Application.run()`, which handles signal management, plugin loading, and sub-command dispatch.
- Developers can extend functionality by adding sub-commands to the configuration or invoking the CLI programmatically via `ContainerCLI.main()`.

## Frequently Asked Questions

### What does the `@main` attribute do in ContainerCLI.swift?

The `@main` attribute marks the `ContainerCLI` struct as containing the program's entry point. This tells the Swift compiler to generate a main function that calls `ContainerCLI.main()`, resulting in a single executable binary named `container` when built.

### How does ContainerCLI handle sub-command dispatch?

The `ContainerCLI` struct delegates sub-command handling to the `Application` type defined in [`Sources/ContainerCommands/Application.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Application.swift). After parsing arguments with `Application.parse(arguments)`, the `run()` method calls `application.run()`, which routes execution to the appropriate sub-command implementation based on the parsed command-line input.

### Can developers invoke the container CLI programmatically?

Yes. Developers can import the `ContainerCLI` module and call `try await ContainerCLI.main()` from within another Swift program. This forwards arguments to the built-in CLI and is useful for building wrapper tools or automating container operations within larger Swift applications.

### Where is the Application type defined?

The `Application` type is defined in [`Sources/ContainerCommands/Application.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Application.swift). This file contains the core command infrastructure that handles validation, plugin discovery via `createPluginLoader()`, signal handling, and the actual execution of sub-commands.