Your First CLI in Swift: From Idea to Ready Tool
\n\nHave you ever wondered how those handy terminal utilities — curl, git, brew — are created? It turns out, writing your own CLI utility in Swift is no harder than making a simple iOS app. Moreover, Swift is perfect for this: it's fast, memory-safe, and works great on both macOS and Linux.
In this article, we'll build a full-fledged console tool from scratch that will parse arguments, output colored text, and even handle errors. You'll learn how to set up a project using Swift Package Manager, integrate the powerful ArgumentParser library, and prepare your utility for publication in Homebrew. Ready? Let's go!
\n\nWhy Swift for CLI is Awesome?
\n\nWhen it comes to building command line tools, many immediately think of Python, Bash, or Go. But Swift is a dark horse that surprises:
\n\n- \n
- Speed on par with C — your utility will fly. \n
- Safe memory management — no segfaults or leaks. \n
- Cross-platform — Swift works great on Linux, so your CLI can even run on servers. \n
- Modern syntax — code reads like good prose. \n
- Huge ecosystem — Swift Package Manager (SPM) gives access to thousands of libraries. \n
By the way, if you already write in Python and want to try something new for CLI, Swift will be an excellent choice: you'll get a native binary with no dependencies and minimal memory usage.
\n\nProject Setup: Swift Package Manager
\n\nFirst, let's create a new project. Open your terminal and run:
\n\nmkdir MyCLI\ncd MyCLI\nswift package init --type executable\n\nThe command creates a standard SPM structure. Pay attention to the Package.swift file — it's the heart of your project. Let's edit it to add a dependency on Apple/Swift ArgumentParser:
// swift-tools-version:5.9\nimport PackageDescription\n\nlet package = Package(\n name: "MyCLI",\n dependencies: [\n .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.0")\n ],\n targets: [\n .executableTarget(\n name: "MyCLI",\n dependencies: [\n .product(name: "ArgumentParser", package: "swift-argument-parser")\n ]\n )\n ]\n)\n\nNow run swift build. SPM will automatically download the library and build the project. If everything goes smoothly — you're ready to write code!
Writing the First Command: Hello World on Steroids
\n\nOpen Sources/MyCLI/main.swift and write a simple command that outputs a greeting. But not just "Hello, World!" — using arguments:
import ArgumentParser\n\nstruct HelloCommand: ParsableCommand {\n static let configuration = CommandConfiguration(\n commandName: "hello",\n abstract: "Outputs a greeting",\n discussion: "Use this command to greet the world or a specific person."\n )\n\n @Argument(help: "The name of the person to greet")\n var name: String = "World"\n\n @Option(name: .shortAndLong, help: "Number of repetitions")\n var count: Int = 1\n\n func run() throws {\n for _ in 0..<count {\n print("Hello, \\(name)! 👋")\n }\n }\n}\n\nHelloCommand.main()\n\nRun: swift run MyCLI hello --count 3 "iOS Developer". You'll see:
Hello, iOS Developer! 👋\nHello, iOS Developer! 👋\nHello, iOS Developer! 👋\n\nNotice: Argumen