Clean, maintainable Package.swift creation and editing using the static property pattern from Facebook iOS SDK. Use when creating new Package.swift files, refactoring existing ones, adding modules/targets to Swift packages, or organizing Swift Package Manager manifests for better maintainability.
From dev-skillsnpx claudepluginhub igor1309/skills --plugin dev-skillsThis skill uses the workspace's default tool permissions.
assets/multi-module-template.swiftassets/single-product-template.swiftreferences/pattern-details.mdSearches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
Create and edit Package.swift files using the clean static property pattern that eliminates magic strings and improves maintainability.
Announce: "I'm using the Swift Package Manifest skill to apply the static property pattern."
Transform verbose, string-heavy Package.swift files into clean, type-safe manifests using extensions with static properties.
Place the main Package declaration at the top, using static properties:
// swift-tools-version: 6.1
@preconcurrency import PackageDescription
let package = Package(
name: "package-name",
platforms: [.iOS(.v15)],
products: [.core],
dependencies: [.externalDep],
targets: [.core, .tests]
)
Follow this extension order (use // MARK: - comments):
To add a new module like ThisFeature:
// Add to Products
private extension Product {
static let thisFeature = library(name: .thisFeature, targets: [.thisFeature])
}
// Add to Targets
private extension Target {
static let thisFeature = target(name: .thisFeature, dependencies: [.core])
}
// Add to Target.Dependency (if needed by other targets)
private extension Target.Dependency {
static let thisFeature = byName(name: .thisFeature)
}
// Add to String Constants
private extension String {
static let thisFeature = "ThisFeature"
}
// Update main declaration
products: [.core, .thisFeature]
targets: [.core, .thisFeature, .tests]
privatedependencies: [] if empty@preconcurrency import PackageDescriptionbyName() for internal targetsproduct() for external packagesSee assets/single-product-template.swift for a complete example.
See assets/multi-module-template.swift for organizing multiple targets.
For 10+ targets, use array grouping:
let package = Package(
name: "my-app",
products: .core + .features,
targets: .core + .features + .tests
)
private extension Array where Element == Product {
static let core: Self = [.domain, .shared]
static let features: Self = [.auth, .payments]
}
// In Package dependencies
dependencies: [.alamofire, .swiftLint]
// In Target dependencies
dependencies: [.alamofire]
// Define in extensions
private extension Target.Dependency {
static let alamofire = product(name: "Alamofire", package: "Alamofire")
}
private extension Package.Dependency {
static let alamofire = package(
url: "https://github.com/Alamofire/Alamofire.git",
from: "5.8.0"
)
}
Group test targets under a nested enum:
private extension Target {
enum Tests {
static let core = testTarget(name: .Tests.core, dependencies: [.core])
static let feature = testTarget(name: .Tests.feature, dependencies: [.thisFeature])
}
}
private extension String {
enum Tests {
static let core = "CoreTests"
static let feature = "ThisFeatureTests"
}
}
For complete pattern documentation and advanced techniques, see references/pattern-details.md.