Package.swift, at a project's root, is genuinely executable Swift code — it imports PackageDescription and constructs a Package value describing dependencies, targets, and products — compiled and run by SPM to produce the actual manifest, unlike the static JSON/YAML/XML configuration files most other languages' package managers use. swift build, swift test, and swift run drive the whole workflow directly from the command line, with Xcode also integrating SPM natively for GUI-based dependency management.
A basic Package.swift
This entire file is genuinely compiled and run — not parsed as data — to produce the Package description SPM actually uses, which is why full Swift syntax (comments, conditionals, computed values) is legal inside it.
// swift-tools-version:5.10
import PackageDescription
let package = Package(
name: "MyLibrary",
products: [
.library(name: "MyLibrary", targets: ["MyLibrary"])
],
dependencies: [
.package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0")
],
targets: [
.target(name: "MyLibrary", dependencies: [.product(name: "NIO", package: "swift-nio")]),
.testTarget(name: "MyLibraryTests", dependencies: ["MyLibrary"])
]
)Building, testing, and running from the command line
All three commands work directly against Package.swift, with no separate build-configuration step needed — SPM reads the manifest, resolves dependencies, and drives the whole process.
$ swift build
$ swift test
$ swift runUsing a package as a dependency
Once added to Package.swift's dependencies array (and the target's own dependencies list), the package's public API is directly importable, exactly like any built-in framework.
import NIO // available once swift-nio is declared as a dependency