CLI framework for Swift: creating powerful console utilities for iOS and macOS
Swift is not only a language for mobile applications. With the advent of Swift Package Manager (SPM) and frameworks like ArgumentParser, developers have gained the ability to create full-fledged console tools for macOS and even for iOS (within server or CI/CD processes). CLI (Command Line Interface) frameworks for Swift allow parsing command line arguments, handling flags, options, and subcommands, as well as generating automatic help.
In this article, we will thoroughly examine one of the most popular and official CLI frameworks — Swift ArgumentParser (developed by Apple). You will learn how to install it via SPM, write a simple console tool, add subcommands and arguments, and see code examples for real-world tasks.
What is a CLI framework for Swift?
A CLI framework is a library that handles the routine work of parsing the command line string. Instead of manually writing loops over CommandLine.arguments, you describe the command structure declaratively: which arguments are required, which are optional, which flags are supported. The framework itself generates help (--help) and handles input errors.
Main features of Swift ArgumentParser:
- Declarative description of arguments and options
- Automatic generation of help and version
- Support for subcommands (like in
git commitorswift build) - Type validation (Int, String, Double, and custom types)
- Integration with SPM and Xcode
Installation via Swift Package Manager
Add the dependency to your project's Package.swift:
// swift-tools-version:5.9import PackageDescription
let package = Package( name: "MyCLITool", dependencies: [ .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.0") ], targets: [ .executableTarget( name: "MyCLITool", dependencies: [ .product(name: "ArgumentParser", package: "swift-argument-parser") ] ) ])Now run swift build — the library will be downloaded and compiled.
Writing your first command
Let's create a simple utility that greets the user by name and age.
import ArgumentParser
struct Greet: ParsableCommand { @Argument(help: "User name") var name: String
@Option(name: .shortAndLong, help: "Age") var age: Int?
mutating func run() throws { if let age = age { print("Hello, \\(name)! You are \\(age) years old.") } else { print("Hello, \\(name)!") } }}
Greet.main()Run the compiled binary:
./MyCLITool "Anna" --age 25# Output: Hello, Anna! You are 25 years old.
./MyCLITool "Maxim"# Output: Hello, Maxim!The automatically generated help (--help) will show all arguments and options.
Subcommands: structure like in real utilities
Often CLI tools have several subcommands: create, delete, list. ArgumentParser supports this out of the box.
import ArgumentParser
struct TaskManager: ParsableCommand { static var configuration = CommandConfiguration( subcommands: [Add.self, List.self, Delete.self] )}
struct Add: ParsableCommand { @Argument(help: "Task text") var text: String
func run() { print("Task added: \\(text)") }}
struct List: ParsableCommand { func run() { print("Task list:") Also in library
Generating PDF Reports in C# (.NET) with iTextSharp and QuestPDF
Bull for JavaScript (Node.js): Complete Guide with Examples
WebSocket Libraries TypeScript: ws and Socket.IO – Complete Guide
Event Bus and Observer Pattern in Go (Golang): pub/sub Implementation
Lottie Android for Kotlin: Complete Guide with Examples