Swift Package Registry
LPM implements SE-0292, the Swift Package Registry standard. Swift Package Manager resolves and fetches LPM packages natively — no plugins, no workarounds.
Setup
One command configures everything — registry scope, authentication, and package signing certificate:
lpm swift-registry
This runs three steps:
- Registers
lpmdevscope with SPM pointing tohttps://lpm.dev/api/swift-registry - Logs in with your LPM token (stored in keychain)
- Installs the LPM signing certificate so SPM trusts package signatures
Prerequisites: You must be logged in (lpm login) and have Swift 5.9+ installed.
Manual Setup
If you prefer to configure manually:
# Set registry scope
swift package-registry set --scope lpmdev https://lpm.dev/api/swift-registry
# Authenticate
swift package-registry login https://lpm.dev/api/swift-registry --token YOUR_LPM_TOKEN --no-confirm
# Install signing certificate (for trusted signature verification)
mkdir -p ~/.swiftpm/security/trusted-root-certs
curl -o ~/.swiftpm/security/trusted-root-certs/lpm.der https://lpm.dev/api/swift-registry/certificate
Installing Packages
lpm install @lpm.dev/acme.swift-logger
The CLI automatically:
- Fetches the package metadata (version, product name)
- Edits your
Package.swift— adds the dependency and product to your target - Runs
swift package resolve
If your project has multiple targets, the CLI prompts which one to add the dependency to. Use --yes to skip prompts and pick the first target.
What it looks like in Package.swift
After lpm install, your manifest looks like:
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "MyApp",
platforms: [.macOS(.v12), .iOS(.v15)],
dependencies: [
.package(id: "lpmdev.acme-swift-logger", from: "1.0.0"),
.package(url: "https://github.com/apple/swift-nio.git", from: "2.60.0"),
],
targets: [
.target(name: "MyApp", dependencies: [
.product(name: "Logger", package: "lpmdev.acme-swift-logger"),
.product(name: "NIOCore", package: "swift-nio"),
]),
]
)
You can also edit Package.swift manually — the .package(id:) syntax is standard SE-0292.
Package Identity
LPM package names map to SE-0292 identifiers:
| LPM Name | SE-0292 Identifier |
|---|---|
@lpm.dev/acme.swift-logger | lpmdev.acme-swift-logger |
@lpm.dev/acme.design-system | lpmdev.acme-design-system |
The pattern is: lpmdev.{owner}-{package-name}. The lpmdev scope tells SPM to fetch from the LPM registry.
Package Signing
All Swift packages published to LPM are signed with a CMS digital signature (ECDSA P-256). When you install the LPM certificate (included in lpm swift-registry), SPM verifies package integrity automatically.
Without the certificate, SPM still resolves packages but shows a warning. To suppress it:
swift package resolve --resolver-signing-entity-checking warn
Transitive Dependencies
LPM packages can depend on other LPM packages. SPM resolves the entire dependency chain through the registry:
MyApp
└── @lpm.dev/acme.swift-network (LPM)
├── @lpm.dev/acme.swift-logger (LPM) ← resolved via registry
└── swift-nio (GitHub)
LPM packages can also depend on regular GitHub-hosted Swift packages. SPM handles both sources in a single resolution pass.
Install vs Source Delivery
lpm install | lpm add | |
|---|---|---|
| Use for | Library dependencies | UI components, templates |
| Managed by | SPM's resolver | You (code copied into your project) |
| Updates | swift package update | Re-run lpm add |
| Transitive deps | Automatic | Manual |
| Customization | Use as-is | Edit freely |
Rule of thumb: If you'd import it, use lpm install. If you'd modify it, use lpm add.
Publishing Swift Packages
Publishing works the same regardless of how consumers install. The CLI auto-detects Swift from Package.swift:
cd my-swift-library
lpm publish
The server automatically:
- Extracts
Package.swiftmetadata (targets, platforms, dependencies) - Creates a zip source archive for SPM
- Signs the archive with LPM's certificate
See Publishing for the full guide.