Skip to content

/commands/swift/swift-package-init

swift package init --type executable: create a Swift package

The commands on this page have not been executed by our verification runner yet.updated
tool
Swift
versions
Swift 5.x – 6.x
os
macos, linux, windows

swift package init --type executable creates a new Swift Package Manager project in the current directory: a Package.swift manifest and a Sources/ folder with the executable target's code. The package takes its name from the directory, or from --name. Build and run it with swift run; use --type library for a reusable module.

Create, build, run

bash
mkdir Hello && cd Hello
swift package init --type executable
swift build                 # debug build in .build/debug
swift run                   # build and run the executable
swift build -c release      # optimized build in .build/release
swift test                  # run tests in Tests/

What the executable template creates

The getting-started guide on swift.org shows the layout for swift package init --name MyCLI --type executable:

text
.
├── Package.swift
├── Sources
│   └── MyCLI
│       └── MyCLI.swift
└── Tests
    └── MyCLITests
        └── MyCLITests.swift

Package.swift declares the package, its products and targets. Each folder under Sources/ is one target, and the folder name must match the target name in the manifest. The entry point is either a main.swift file with top-level code or a type marked @main; a target cannot have both. Build output goes to .build/ (change it with --scratch-path), which belongs in .gitignore.

Package types

--typeCreates
library (default)A library target, a test target and a library product other packages can depend on
executableAn executable target you can swift run; start here for a small program
toolAn executable that uses Swift Argument Parser (Swift 5.9+); start here for a CLI with many options
macroA Swift macro package (Swift 5.9+); pulls in swift-syntax
build-tool-pluginA plugin that runs during the build, for example to generate source files
command-pluginA plugin you invoke on demand with swift package <command>
emptyOnly Package.swift, for laying out targets by hand

Other useful options

OptionEffect
--name NAMEPackage name; the default is the name of the current directory
--package-path DIRCreate the package in DIR instead of the current directory
--enable-swift-testing / --disable-swift-testingGenerate tests for the Swift Testing library, or not
--enable-xctest / --disable-xctestGenerate tests for XCTest, or not

Run swift package init --help to see the list for the installed toolchain; the template set and the test options depend on the Swift version.

Add a dependency

Package.swift
// swift-tools-version: 5.9
import PackageDescription

let package = Package(
    name: "Hello",
    dependencies: [
        .package(url: "https://github.com/apple/swift-argument-parser", from: "1.3.0"),
    ],
    targets: [
        .executableTarget(
            name: "Hello",
            dependencies: [.product(name: "ArgumentParser", package: "swift-argument-parser")]
        ),
    ]
)
bash
swift package resolve       # fetch dependencies and write Package.resolved
swift package update        # move to the newest allowed versions

The first comment line, // swift-tools-version:, is required: it sets the minimum Swift version that can read the manifest and the manifest API available. swift package resolve records the exact versions it picked in Package.resolved; commit that file for executables so every build uses the same dependency versions. For a library, the version requirement in from: is what consumers see, so keep it as loose as your code allows.

FAQ

Does swift package init create a new folder?

It works on the package path, which is the current directory unless you pass --package-path. Create and enter the folder first, or pass --name to set the package name independently of the folder name.

What is the difference between --type executable and --type tool?

Both produce a program you can swift run. The tool template also adds a dependency on Swift Argument Parser and a command type that parses options, which is the better start for a CLI with flags.

Can I use main.swift and @main together?

No. A target has either a main.swift file with top-level code or a type marked @main as its entry point, not both.

Sources