LPM CLI

Using LPM CLI with Swift

SPM integration via SE-0292 — login, install, publish.

LPM.dev Registry speaks the SE-0292 Swift Package Registry API, so Swift Package Manager (SPM) can resolve hosted Swift packages natively. LPM CLI performs the required Registry setup as part of installation.

Prerequisites

  • LPM CLI installed — see Installation.
  • Swift toolchain installed.
  • An lpm.dev account, logged in (lpm login).

Installing a Swift package

lpm install @lpm.dev/owner.swift-pkg
lpm install @lpm.dev/owner.swift-pkg@1.2.0      # specific version
lpm install --yes @lpm.dev/owner.swift-pkg      # choose the first eligible target

On the first Swift install in an unconfigured project, LPM CLI:

  1. Sets the lpmdev scope to the LPM.dev Registry SE-0292 endpoint.
  2. Passes the current LPM.dev Registry session to SPM.
  3. Installs the Registry CMS signing certificate.
  4. Configures the lpmdev signing-trust policy.
  5. Updates Package.swift and runs swift package resolve.

Setup failures abort the install instead of leaving a partially configured trust path. One eligible target is selected automatically. With multiple eligible targets, a normal install asks which target should receive the dependency; -y / --yes skips that selector and chooses its default, the first eligible target.

During later HTTPS installs, LPM CLI signs in to SPM again even when the Registry scope matches. A rejected stored bearer causes one session refresh and one login retry.

The same routing applies in workspaces. Use -w for a root Package.swift, run from a member directory for that member, or use --filter to select Swift members. LPM CLI mutates, configures, reports, and runs swift package resolve from the same selected directory. In mixed JavaScript/Swift workspaces, Swift versions go only through SE-0292 while JavaScript versions retain normal package.json installation.

Use lpm install for Swift dependencies. lpm add is the legacy source-delivery path and is not the normal SPM dependency workflow.

You do not need to run lpm swift-registry before installing. That command remains available for explicit repair and certificate refresh:

lpm swift-registry --force

See the trust model for what package signing currently attests to and why the lpmdev scope uses a dedicated trust policy.

Publishing a Swift package

LPM CLI detects a Swift package from Package.swift at the repository root.

lpm publish

The publish pipeline:

  • Packs the repo into a tarball.
  • Generates a .zip source archive with the SE-0292-required {pkgName}-{version}/ top-level wrapper.
  • Computes the SHA-256 checksum that SPM expects.
  • Generates a CMS-1.0.0 detached signature (ECDSA P-256 / SHA-256) with the LPM.dev Registry signing cert.
  • Uploads tarball + zip + signature to lpm.dev.

After publish, lpm install configures SPM when needed and resolves the package by its LPM.dev Registry identity.

Identity mapping

LPM.dev Registry packages are named @lpm.dev/owner.pkg-name. SE-0292 scopes can't contain dots, so LPM CLI maps them when surfacing to SPM:

LPM.dev Registry nameSPM identity
@lpm.dev/owner.pkg-namelpmdev.owner_pkg-name

The _ between owner and package name is the unambiguous separator: LPM.dev Registry forbids _ in both owner and package name, so the boundary remains clear when either half contains hyphens. You do not need to deal with the SPM identity by hand; lpm install performs the translation.

Verifying signatures

LPM.dev Registry serves the CMS signing certificate at https://lpm.dev/api/swift-registry/certificate in DER form. On every automatic setup check, LPM CLI validates the bounded DER response, compares it with the local certificate, and verifies the complete default and lpmdev signing policy—even when the scope URL already matches. Stale, malformed, missing, or mismatched state is atomically repaired before SPM resolves the dependency.

Signatures are surfaced in three places per release:

  • The release metadata JSON (base64 CMS).
  • The Digest HTTP response header on tarball download.
  • A comment block in the Package.swift manifest response.

If the cert rotates, re-run lpm swift-registry --force. Failed --force re-downloads are fatal — the CLI will not silently fall back to the stale cert.

For the trust-model rationale (why the cert is self-signed, why SPM uses a silentAllow scope override rather than a trust-store entry, what the signature actually attests to), see Trust model.

Common pitfalls

  • lpm add for Swift is the legacy path. Use lpm installadd is source-delivery, not what you want for a runtime SPM dep.
  • Package.swift must use the SE-0292 identity (lpmdev.owner_pkg-name), not the LPM.dev Registry-native form. lpm install writes it correctly; if you hand-edit, mind the format — the _ separates owner from package name.
  • Refresh after a documented certificate rotation. Run lpm swift-registry --force. A failed forced refresh is fatal; LPM CLI does not silently keep the stale certificate.

See also