Articles, podcasts and news about Swift development, by John Sundell.

Combined Swift packages

Published on 12 Apr 2019

If we want to distribute a Swift package as both a library that other tools can import, and as a command line tool, all we have to do is to define two separate targets and products.

Here’s an example Package.swift file in which we’re doing exactly that:

// swift-tools-version:5.0

import PackageDescription

let package = Package(
    name: "Plot",
    products: [
        // If we want to distribute a Swift package as both a
        // library and a command line tool, one way to do that
        // is to simply use lower case characters for the CLI.
        .library(name: "Plot", targets: ["Plot"]),
        .executable(name: "plot", targets: ["PlotCLI"])
    dependencies: [
        .package(url: "", from: "3.1.0"),
        .package(url: "", from: "0.2.1"),
        .package(url: "", from: "0.2.0")
    targets: [
            name: "Plot",
            dependencies: ["Files", "Sweep", "Codextended"]
            // We can still name our target "CLI", to make it
            // easier to see the difference between our CLI
            // and our library in Xcode.
            name: "PlotCLI",
            dependencies: ["Plot"]
            name: "PlotTests",
            dependencies: ["Plot", "Codextended"]

Support Swift by Sundell by checking out this sponsor:


Bitrise: My favorite continuous integration service. Automatically build, test and distribute your app on every Pull Request, and use a new powerful suite of add-ons to visualize your test results, to ship your app with ease, and to add crash and performance monitoring to your project. Get started for free.