Swift Package Registry
Install and publish Swift packages with registry identities, signed archives, version-specific manifests, and native resolution.
LPM.dev Registry serves Swift packages through the SE-0292 registry API. LPM CLI configures Swift Package Manager, updates the project, and runs native dependency resolution.
# Install a Swift library into a SwiftPM or Xcode project
lpm install @lpm.dev/owner.swift-kit
# Select the first eligible target without a prompt
lpm install @lpm.dev/owner.swift-kit --yes
# Repair registry configuration and retrieve the current certificate
lpm swift-registryFree releases support anonymous access. Protected releases require credentials with access to the package.
Use lpm install for native dependencies. lpm add copies source files into a project.
Package identities
The Registry uses the SwiftPM scope lpmdev. It translates the owner and package name into one registry identity:
| LPM.dev Registry package | SwiftPM identity |
|---|---|
@lpm.dev/owner.swift-kit | lpmdev.owner_swift-kit |
@lpm.dev/myorg.networking | lpmdev.myorg_networking |
The underscore separates the owner from the package name. Neither component can contain an underscore. LPM CLI writes the translated identity into the project automatically.
This integration serves LPM.dev Registry packages. The CLI's npm package workflow remains registry-agnostic.
Native installation
lpm install @lpm.dev/owner.swift-kit@1.2.0
lpm install @lpm.dev/owner.swift-kit@1.2.0 --exact --yesLPM CLI first reads package metadata to select a release and an importable library product. SwiftPM then resolves the project's native dependency graph.
For a SwiftPM project, the CLI updates Package.swift and connects the product to an eligible target. For Xcode, it uses a generated local package wrapper.
One eligible target is selected automatically. With multiple targets, an interactive install opens a selector. --yes selects the first eligible target.
The default requirement permits compatible releases up to the next major version. --exact saves an exact requirement.
Reinstallation still checks access and runs native resolution. An existing declaration does not prove that dependency files are present.
Existing products from the same package retain their conditions and module aliases. A version update preserves comments and other selected products. If a requirement uses an unsupported expression, the CLI stops without changing the manifest.
After resolution, the CLI checks required products and access to each resolved LPM.dev Registry dependency. A failure restores the previous project declarations and lockfiles.
That rollback does not restore global SwiftPM configuration, certificates, or caches.
Automatic registry configuration
Each native install checks the project's registry scope, downloads the current certificate, and checks the signing policy.
The project scope points lpmdev to:
https://lpm.dev/api/swift-registryThe certificate is security/trusted-root-certs/lpm.der inside the SwiftPM user directory. Signing policy uses configuration/registries.json in that directory.
Free-package installation starts anonymously. If native resolution needs protected dependencies, the CLI can retry with available credentials.
An explicit CLI token takes precedence over session discovery. Otherwise, the CLI uses its authentication configuration.
lpm.json does not replace the native registry scope or signing policy. Use lpm swift-registry for explicit setup and repair.
Malformed or unsupported existing SwiftPM configuration stops setup. The CLI preserves that file so you can correct it without losing other registry entries.
Trust model
New publications require a signed source archive and signed manifests. If Registry signing is unavailable or invalid, publication fails before the release is saved.
SwiftPM checks the archive checksum and its detached CMS signature. Each served manifest has a separate signature over that manifest's bytes.
The Registry signs these artifacts. The signatures do not establish the package author's identity.
The current trust policy combines cryptographic integrity checks with HTTPS origin authentication. The certificate and package bytes come from the configured Registry origin.
For that hostname, onUntrustedCertificate is silentAllow. This accepts a valid signature without a certificate chain to a trusted root. It does not pin a signer.
Unsigned packages remain errors. Setup also enforces strict default signing actions, while preserving unrelated configuration and other registry overrides.
Historical unsigned releases can still be served by the Registry. The default CLI signing policy rejects them.
Publish a Swift package
# Check the package before upload
lpm publish --check
# Publish the package
lpm publishThe published archive must contain Package.swift at its root. The CLI inspects the source with Swift before upload, including during --check.
The Registry independently inspects the uploaded source. Products, targets, platforms, and dependencies come from that inspection.
The Registry creates a ZIP archive with one top-level package directory. It preserves ordinary file permissions and executable bits, and removes special permission bits.
The release includes a SHA-256 checksum and a detached archive signature. The Registry signs the manifest separately before serving it.
Manifests for different Swift versions
A release can include a root manifest and version-specific manifests:
Package.swift
Package@swift-6.swift
Package@swift-6.2.swiftEach alternate filename must match its swift-tools-version declaration. For example, Package@swift-6.swift declares // swift-tools-version: 6.0.
Versions use decimal components without leading zeros. 6, 6.0, and 6.0.0 mean the same tools version.
Each manifest must declare a distinct tools version, including the root manifest. An alternate can require an older tools version than the root.
The Registry inspects every manifest, including alternatives that its compiler does not select automatically. Any invalid or unsupported manifest stops publication.
The release can contain at most 32 root-level manifests. Each manifest can contain up to 1 MiB, with a combined limit of 4 MiB.
SwiftPM selects the manifest through its native rules:
- It checks filenames for its exact patch, minor, and major tools versions, in that order.
- Otherwise, it finds the highest alternate version that does not exceed its tools version.
- It uses that alternate if it requires newer tools than the root, or the root requires unsupported tools.
- Otherwise, it uses the root manifest.
For SwiftPM 6.4, Package@swift-6.swift takes precedence over Package@swift-6.3.swift because the exact major filename wins first.
LPM CLI uses the selected manifest's products and platforms. For Xcode projects, SwiftPM and Xcode must report matching tools versions before installation changes project files.
Older CLI releases cannot install these variant releases. Update LPM CLI before installation.
Each served manifest has its own signature. The source archive retains all original manifest files.
See lpm publish for publication configuration and access controls.
Pool accounting
After a successful install, LPM CLI reports the resolved dependency graph. LPM.dev Registry uses that graph to calculate Pool depth for eligible protected packages.
Free packages receive no Pool credit and require no download evidence. Git dependencies remain in the graph so registry packages behind them retain their depth.
Direct SwiftPM or Xcode downloads record provisional credit at depth zero. A later CLI report supplies the resolved depth.
Repeated downloads do not create duplicate monthly credit. Publisher and organization-member access do not earn credit for the publisher.
Recover from an install failure
If scope, certificate, or signing-policy configuration needs repair, run:
lpm swift-registryEach setup downloads the current certificate and replaces changed bytes. --force also replaces a matching certificate. A failed download preserves the previous certificate.
If protected packages require authentication, sign in and repeat installation:
lpm login
lpm install @lpm.dev/owner.swift-kit --yesIf download evidence is missing after a credential change, force a fresh native resolution:
lpm install @lpm.dev/owner.swift-kit --force --yesFor Swift packages, --force resets generated SwiftPM state and bypasses the shared dependency cache. It preserves project sources.
If publication requires a newer Swift tools version, use a version supported by both your local compiler and the Registry validator.
Registry endpoints
The hosted API serves the lpmdev scope:
| Request | Response |
|---|---|
GET /{scope}/{name} | Available releases. |
GET /{scope}/{name}/{version} | Release metadata, archive checksum, and signing information. |
GET /{scope}/{name}/{version}.zip | Source archive with a checksum header. |
GET /{scope}/{name}/{version}/Package.swift | Signed root manifest and links to available alternatives. |
GET /{scope}/{name}/{version}/Package.swift?swift-version=6.0 | Signed manifest for the requested tools version. |
PUT / or POST / | Authentication at the registry root. |
GET /certificate | Public signing certificate in DER format. |
A valid unavailable tools version redirects to the root manifest. Invalid or repeated swift-version values return HTTP 400.
Paths are relative to /api/swift-registry. Native SwiftPM commands use these endpoints after CLI setup.