Download Beam

Building Swift CLI Tools on macOS: Terminal Workflow with Claude Code and Beam

February 11, 2026 • NextUp Technologies • 8 min read

When most developers think of Swift, they think of iOS apps and Xcode storyboards. But Swift has quietly become one of the best languages for building command-line tools and server-side applications -- especially on macOS, where its tight integration with the system gives you performance and capabilities that other languages simply cannot match.

The best part? Swift CLI development is entirely terminal-based. No Xcode required. Just swift build, swift test, and swift run -- the trifecta of Swift Package Manager commands that power a fast, iterative development loop. Pair that workflow with Claude Code for AI-assisted coding and Beam for terminal organization, and you have a native macOS development environment that is hard to beat.

Why Swift for CLI Tools?

Swift is not just an alternative to Python or Go for command-line tools -- it brings genuine advantages to the table:

Swift Package Manager: Your Entire Build System in the Terminal

Swift Package Manager (SPM) is Swift's native build system and dependency manager. Unlike Xcode projects with their opaque .xcodeproj files, SPM uses a simple, declarative Package.swift manifest that you can read, edit, and version control with ease.

Here is how to scaffold a new CLI project from scratch:

# Create and initialize a new executable package
mkdir MyCLI && cd MyCLI
swift package init --type executable

# This creates:
# Package.swift      - Your project manifest
# Sources/main.swift - Entry point
# Tests/             - Test directory

The three commands you will use constantly:

# Compile your project (debug mode by default)
swift build

# Run your tests
swift test

# Build and run in one step
swift run MyCLI

For release builds with full optimizations:

# Optimized release build
swift build -c release

# The binary lands in .build/release/MyCLI
# Copy it to /usr/local/bin or distribute it directly

Why Terminal-Based Swift Beats Xcode for CLI Work

Xcode is excellent for GUI apps, but for CLI tools it adds unnecessary overhead. SPM in the terminal gives you faster iteration cycles, easier CI/CD integration, and the ability to use any editor you want. You also avoid the friction of Xcode project settings, build schemes, and target configurations that have no relevance for command-line executables.

Building Professional CLIs with swift-argument-parser

Apple's swift-argument-parser is the standard library for building CLI tools in Swift. It gives you automatic help generation, type-safe argument parsing, subcommands, and shell completions -- all declared using Swift's property wrapper syntax.

First, add it to your Package.swift:

// swift-tools-version: 6.0
import PackageDescription

let package = Package(
    name: "MyCLI",
    platforms: [.macOS(.v13)],
    dependencies: [
        .package(
            url: "https://github.com/apple/swift-argument-parser",
            from: "1.5.0"
        ),
    ],
    targets: [
        .executableTarget(
            name: "MyCLI",
            dependencies: [
                .product(
                    name: "ArgumentParser",
                    package: "swift-argument-parser"
                ),
            ]
        ),
        .testTarget(
            name: "MyCLITests",
            dependencies: ["MyCLI"]
        ),
    ]
)

Then build a command with subcommands:

import ArgumentParser
import Foundation

@main
struct MyCLI: ParsableCommand {
    static let configuration = CommandConfiguration(
        commandName: "mycli",
        abstract: "A developer utility for project management.",
        version: "1.0.0",
        subcommands: [Init.self, Build.self, Deploy.self]
    )
}

struct Init: ParsableCommand {
    static let configuration = CommandConfiguration(
        abstract: "Initialize a new project."
    )

    @Argument(help: "The project name.")
    var name: String

    @Option(name: .shortAndLong, help: "Project template to use.")
    var template: String = "default"

    @Flag(name: .shortAndLong, help: "Enable verbose output.")
    var verbose: Bool = false

    func run() throws {
        if verbose {
            print("Creating project '\(name)' with template '\(template)'...")
        }
        // Project initialization logic here
        print("Project '\(name)' created successfully.")
    }
}

Run it and get automatic help for free:

$ swift run MyCLI --help
OVERVIEW: A developer utility for project management.

USAGE: mycli <subcommand>

OPTIONS:
  --version     Show the version.
  -h, --help    Show help information.

SUBCOMMANDS:
  init          Initialize a new project.
  build         Build the current project.
  deploy        Deploy to production.

$ swift run MyCLI init MyApp --template vapor --verbose
Creating project 'MyApp' with template 'vapor'...
Project 'MyApp' created successfully.

The Beam Workspace Setup for Swift CLI Development

Swift CLI development involves juggling builds, tests, running your tool, AI assistance, and version control. Beam workspaces keep all of this organized in a single, switchable context.

Here is the workspace layout I recommend. Create a workspace called "MyCLI" and set it up with five tabs:

Pro Tip: Split Panes for Build + Test

Press ⌘⌥⌃T to split Tab 1 into two panes. Put swift build on the left and swift test on the right. Now you can see compile errors and test results side by side without switching tabs. This is especially valuable when refactoring, since you can immediately see if your changes break anything.

Switch between tabs with ⌘1 through ⌘5. Save the entire layout with ⌘S so you can restore it tomorrow and pick up exactly where you left off.

Server-Side Swift: Vapor and Hummingbird Workspace Setup

Swift is not just for CLI tools. Server-side Swift frameworks like Vapor and Hummingbird let you build high-performance web APIs using the same language, type system, and package ecosystem. The terminal workflow is nearly identical.

Create a new Beam workspace called "MyAPI" with these tabs:

Switch between your CLI workspace and server workspace with ⌘⌥←→. Each workspace maintains its own state -- your server keeps running in one workspace while you build CLI tools in another.

Swift 6 Strict Concurrency: Where Claude Code Shines

Swift 6 introduced strict concurrency checking, and it can be a challenging migration. The compiler now enforces Sendable conformance across concurrency boundaries, which means code that compiled fine in Swift 5 may suddenly produce dozens of warnings or errors.

This is exactly where Claude Code becomes invaluable. Ask it to help with common concurrency patterns:

I'm getting 'Sendable' warnings on my DatabaseManager class that uses a connection pool. Can you make it thread-safe using Swift 6 concurrency? Here's the current code...

Claude Code can help you with:

// Before: Swift 5 pattern that triggers warnings in Swift 6
class DatabaseManager {
    var connectionPool: [Connection] = []

    func query(_ sql: String) async throws -> [Row] {
        let conn = connectionPool.first!
        return try await conn.execute(sql)
    }
}

// After: Swift 6 safe pattern using an actor
actor DatabaseManager {
    private var connectionPool: [Connection] = []

    func query(_ sql: String) async throws -> [Row] {
        let conn = connectionPool.first!
        return try await conn.execute(sql)
    }
}

Project Memory: Teaching Claude Code Your Swift Conventions

Every Swift project has its own conventions -- naming patterns, preferred libraries, target structure, and coding style. Claude Code's project memory feature (via CLAUDE.md) lets you persist this context so Claude understands your project from the start of every session.

Here is an example CLAUDE.md for a Swift CLI project:

# Project: MyCLI

## Build
- Build: swift build
- Test: swift test
- Run: swift run MyCLI
- Release: swift build -c release

## Architecture
- Entry point: Sources/MyCLI/MyCLI.swift (@main struct)
- Commands in Sources/MyCLI/Commands/
- Models in Sources/MyCLI/Models/
- Uses swift-argument-parser for CLI parsing
- Uses Swift 6 strict concurrency (no @unchecked Sendable)

## Conventions
- All commands are ParsableCommand structs
- Error handling via custom CLIError enum
- Verbose flag on all commands for debug output
- Tests mirror source structure: Tests/MyCLITests/Commands/

With this in place, Claude Code knows how to build your project, where to find things, and which patterns to follow when generating new code. No more repeating yourself at the start of every session.

Cross-Compilation and Distribution

Once your CLI tool is ready, you need to distribute it. Swift makes building universal binaries straightforward on macOS:

# Build a universal binary (Apple Silicon + Intel)
swift build -c release --arch arm64 --arch x86_64

# Check the architectures
file .build/apple/Products/Release/MyCLI
# MyCLI: Mach-O universal binary with 2 architectures:
#   arm64, x86_64

# Strip debug symbols for a smaller binary
strip .build/apple/Products/Release/MyCLI

# Copy to a standard location
cp .build/apple/Products/Release/MyCLI /usr/local/bin/

For broader distribution, consider these options:

Linux Cross-Compilation

If you need to target Linux (for server deployment or CI), Swift supports cross-compilation with the Swift SDK. Install a Linux SDK with swift sdk install and build with swift build --swift-sdk x86_64-swift-linux-musl. This produces a statically linked Linux binary right from your Mac -- no Docker required for the build step.

Why Swift Developers Should Invest in Terminal Workflows

The Swift ecosystem is evolving rapidly beyond iOS. Server-side Swift is production-ready, CLI tools built with Swift rival Go and Rust in performance, and Apple continues to invest heavily in SPM and the open-source Swift toolchain.

By building a terminal-first workflow with Beam and Claude Code, you get:

Swift is no longer just an iOS language. It is a systems programming language with native performance, a strong type system, modern concurrency, and a growing ecosystem for CLI and server development. The terminal is where that work happens best.

Ready to Build Swift CLI Tools with Beam?

Download Beam free and set up your perfect Swift development workspace with organized tabs, split panes, and Claude Code integration.

Download Beam for macOS

Summary

Swift CLI development is a fully terminal-based workflow, and it deserves a terminal environment built for that kind of work. Here is what we covered:

Happy building!