Swiftpack.co - Package - kylef/Commander
Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.


Build Status

Commander is a small Swift framework allowing you to craft beautiful command line interfaces in a composable way.


Simple Hello World
import Commander

let main = command { (filename:String) in
  print("Reading file \(filename)...")

Type-safe argument handling

The closure passed to the command function takes any arguments that conform to ArgumentConvertible, Commander will automatically convert the arguments to these types. If they can't be converted the user will receive a nice error message informing them that their argument doesn't match the expected type.

String, Int, Double, and Float are extended to conform to ArgumentConvertible, you can easily extend any other class or structure so you can use it as an argument to your command.

command { (hostname:String, port:Int) in
  print("Connecting to \(hostname) on port \(port)...")
Grouping commands

You can group a collection of commands together.

Group {
  $0.command("login") { (name:String) in
    print("Hello \(name)")

  $0.command("logout") {


$ auth

    $ auth COMMAND


    + login
    + logout

$ auth login Kyle
Hello Kyle
$ auth logout

Describing arguments

You can describe positional arguments and options for a command to auto-generate help. This is done by passing in descriptors of these arguments.

For example, for fixed positional arguments with descriptions, you can use:

    Argument<String>("name", description: "Your name"),
    Argument<String>("surname", description: "Your surname"),
    Argument<Int>("count", description: "Number of times to print")
) { name, surname, count in
    for _ in 0..<count {
        print("Hello \(name) \(surname)")

Keep in mind you have to pass 3 required arguments.

Another example, to describe a command which takes two (optional) options, --name and --count where the default value for name is world and the default value for count is 1.

  Option("name", default: "world"),
  Option("count", default: 1, description: "The number of times to print.")
) { name, count in
  for _ in 0..<count {
    print("Hello \(name)")
$ hello --help

    $ hello

    --count - The number of times to print.

$ hello
Hello world

$ hello --name Kyle
Hello Kyle

$ hello --name Kyle --count 4
Hello Kyle
Hello Kyle
Hello Kyle
Hello Kyle
Types of descriptors
  • Option - An optional option with a value.
  • Options - A option with a value which can be used multiple times, your command is passed an array containing all option values. You need to specify ahead of time how many values you expect. Example: --myOption value1 value2 value3
  • VariadicOption - Same as options, but instead of a fixed count of values, the user can just repeat the option with additional values. Example: --myOption value1 --myOption value2
  • Flag - A boolean, on/off flag.
  • Argument - A positional argument.
  • VariadicArgument - A variadic argument

NOTE: It's important to describe your arguments after options and flags so the parser can differentiate between --option value and --flag argument.

Using the argument parser

NOTE: ArgumentParser itself is ArgumentConvertible so you can also get hold of the raw argument parser to perform any custom parsing.

command { (name:String, parser:ArgumentParser) in
  if parser.hasOption("verbose") {
    print("Verbose mode enabled")

  print("Hello \(name)")
$ tool Kyle --verbose
Verbose mode enabled
Hello Kyle

Examples tools using Commander


You can install Commander in many ways, with SPM (Swift Package Manager), Conche, CocoaPods or CocoaPods-Rome.

Frameworks and rpath

It's important to note that the .framework or dynamic library file for Commander (and any other dependency) must be available at run-time for your command line tool. Unless you are using SPM.

Applications will look in their rpath which contains paths of where it expects the .frameworks to be found at.

Using a Swift script, you can use the -F flag for setting framework search paths, as follows:

#!/usr/bin/env xcrun swift -F Rome

import Commander

For compiled Swift code, you will need to add an rpath pointing to your dependency frameworks, as follows:

$ install_name_tool -add_rpath "@executable_path/../Frameworks/"  "bin/querykit"

Where "../Frameworks" relative to the executable path is used to find the frameworks and bin/querykit is the executable.

When installing your executable on other systems it's important to copy the frameworks and the binary.



CommandType is the core protocol behind commands, it's an object or structure that has a run method which takes an ArgumentParser.

Both the command functions and Group return a command that conforms to CommandType which can easily be interchanged.

protocol CommandType {
  func run(parser:ArgumentParser) throws

The convenience command function takes a closure for your command that takes arguments which conform to the ArgumentConvertible protocol. This allows Commander to easily convert arguments to the types you would like to use for your command.

protocol ArgumentConvertible {
  init(parser: ArgumentParser) throws

The ArgumentParser is an object that allowing you to pull out options, flags and positional arguments.


Commander is available under the BSD license. See the LICENSE file for more info.


Stars: 1427



0.9.1 - 2019-09-23T20:43:23


  • Usage/help output for commands which contain flags will now contain the short flag, for example, -v, --verbose. #71

Bug Fixes

  • Fixed ordering of flags in the "Unknown Arguments" help output of a command. Flags have previously been stored in an un orderered set and thus upon printing them back out their order was not persisted and a flag part such as -user can be printed as -usre. #78

0.9.0 - 2019-06-12T02:57:42


  • Support for Swift < 4.2 has been removed.


  • Added syntax for using array as a type with Argument instead of using VariadicArgument:

    command(Argument<[String]>("names")) { names in }
  • Added support for optional arguments and options, for example:

    command(Argument<String?>("name")) { name in }
    command(Option<String?>("name", default: nil)) { name in }
  • Added support for using -- to signal that subsequent values should be treated as arguments instead of options.
    Tamas Lustyik

  • Output of --help for group commands will now sort the commands in alphabetical order.
    Cameron Mc Gorian

Bug Fixes

  • Showing default values for custom ArgumentConvertible types are now supported in the --help output of commands.

  • Only print errors in red if the output terminal supports ANSI colour codes. #58

  • ArgumentParser.isEmpty will now return empty for empty arguments.

0.8.0 - 2017-10-14T11:09:44


  • Consolidate the argument descriptors:
    • All Option-related types now have a validator.
    • All Option-related types now have a flag parameter.
    • All constructors have the same constructor arguments order. #35

Bug Fixes

  • Restores compatibility with Linux.

0.7.1 - 2017-09-28T12:21:19

Bug Fixes

  • The Swift Package now contains the Commander library product.

0.7.0 - 2017-09-28T12:21:08

Switches to Swift 4.0.

Bug Fixes

  • Better detection of ANSI support in output tty. #43

0.6.0 - 2016-11-27T18:15:02


  • VariadicArgument now supports an optional validator.
  • Adds support for variadic options, allowing the user to repeat options to provide additional values. #37
  • Argument descriptions are now printed in command help. #33
  • Default option and flag default values will now be shown in help output. Only default option types of String and Int are currently supported in help output. #34

Bug Fixes

  • VaradicArgument has been renamed to VariadicArgument.

0.4.1 - 2016-02-16T18:29:42

Bug Fixes

  • Fix a potential crash when UsageError is thrown on Linux.
  • --help output now wraps arguments in diamonds <>.

- 2015-12-04T20:46:58

  • Commander can now run on Linux.

- 2015-12-04T18:11:59

  • Commander can now be installed with SPM (Swift Package Manager).
Bug Fixes
  • Fix an issue where shifting flags don't shift the flag itself. This caused one-charter options to become broken.

- 2015-11-22T21:54:48

No public facing changes.

- 2015-11-22T21:52:51

  • Removes dependency on Objective-C Foundation.

- 2015-11-22T21:52:10

  • Convenience commands can now throw

  • You can now supply a falseName and falseFlag when creating flags.

    Flag("verbose", flag: "v", disabledName": "no-verbose", disabledFlag: "x")
  • You can supply your own unknownCommandhelper within a group.

  • Arguments can now have a description.

  • Support for variadic arguments.

Bug Fixes

  • When invoking a command using a described argument, the argument will know throw an error when the argument is missing.
  • Errors are now thrown when a described command receives unknown flags or arguments.

Commander - 2015-09-24T18:17:34

Introduction of Commander.