Publishing your first package
From lpm init to lpm publish, with quality checks and provenance.
This guide walks through publishing a package from scratch. By the end you'll have a package on the LPM.dev Registry that anyone you grant access to can lpm install. We'll cover quality gates, secret scanning, and provenance — the things you can't see from the command name alone.
1. Authenticate
lpm loginOpens your browser, you authenticate against the LPM.dev Registry, LPM CLI captures the redirect token and stores it in your OS keychain. You only do this once per machine.
lpm whoamiConfirms the identity, plan tier, and any orgs you belong to.
2. Create the package
mkdir my-pkg && cd my-pkg
lpm init --lpmlpm init --lpm walks you through owner / name / version / description. The published name will be @lpm.dev/<owner>.<name> — pick an owner you've claimed on the LPM.dev Registry (or one your org owns). Plain lpm init asks for the target first; choose LPM.dev Registry package for this guide.
For a non-interactive bootstrap (CI scripts):
lpm init --lpm -y --owner <owner> --name <name>Plain lpm init -y is still valid and defaults to an LPM.dev Registry package, but the explicit flags avoid leaving placeholder owner/name values in automation.
3. Write your code
Build out the package — src/ (or wherever), dist/ (your build output), README, license. The defaults lpm init writes to package.json (substituting the owner/name you supplied):
{
"name": "@lpm.dev/<owner>.<name>",
"version": "1.0.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"type": "module",
"license": "MIT",
"files": ["dist"],
"packageManager": "lpm@<version>"
}It also writes an AGENTS.md package-manager hint so coding agents in the repo use lpm install, lpm add, and lpm run.
Tighten files to whatever you actually want shipped. Anything not listed (README, LICENSE, package.json) is included by default per npm convention.
4. Preview the publish
lpm publish --dry-runRuns every step except the upload: packs the tarball, scans for hardcoded secrets, computes the quality score. If anything's wrong, this is where you find out.
lpm publish --checkEven shorter — only runs the quality report. Useful as a pre-commit hook.
5. Set a quality floor (optional)
lpm publish --min-score 80Aborts the publish if the quality score is below 80. Pairs well with CI gates — your team can't ship a package missing a README, types, or a license without explicit override.
The score is computed from readme presence/length, license declaration, types coverage, test signals, and maintenance heuristics. See lpm quality to view the report for an already-published LPM.dev Registry package.
6. Publish
lpm publishPack → secret scan → quality report → confirmation prompt → upload. Skip the prompt with -y (good in CI).
The package starts in private distribution mode — only you (and anyone you grant access to) can install it. To make it discoverable or paid, flip the distribution mode in the LPM.dev Registry dashboard:
| Mode | What it means |
|---|---|
| Private (default) | Only the publisher and granted users can install. Metadata is not public. |
| Pool | Metadata is public. Installs gated to pool subscribers. Publisher earns a share of pool revenue. |
| Marketplace | Installs require a license purchase. |
Mode changes are irreversible — going public is a one-way door. See Distribution mode.
7. (Optional) Provenance
In CI with an audience-sigstore OIDC token — GitHub Actions or GitLab CI:
lpm publish --provenance
lpm publish --npm --provenanceGenerates a Sigstore-signed attestation that proves which workflow built the tarball and which commit it came from. With --npm, LPM CLI attaches npm's expected {name}-{version}.sigstore bundle in the publish payload. Consumers can verify provenance via the audit pipeline or the registry UI.
--provenance fails loud (non-zero exit) if no usable Sigstore-audience token is found or if Sigstore signing fails — it never silently publishes without provenance. Useful as a hard gate in security-critical packages.
On GitHub Actions, enable permissions: id-token: write on the job. On GitLab CI, mint SIGSTORE_ID_TOKEN via the id_tokens block with aud: sigstore. Other platforms aren't supported.
For npm-compatible targets, provenance requires public access. LPM CLI's npm default is public for scoped and unscoped packages. If repo config enables provenance but a one-off publish should skip it, pass --no-provenance.
8. Publishing elsewhere
lpm publish defaults to the LPM.dev Registry. To target other registries:
lpm publish --npm # registry.npmjs.org
lpm publish --github # GitHub Packages
lpm publish --gitlab # GitLab Packages
lpm publish --publish-registry https://r.example.com # custom npm-compatibleYou must have auth for the selected target first: lpm login --npm opens npm's browser login, while lpm login --github / --gitlab can use existing gh / glab auth without storing a copied token. Custom registries still use lpm login --login-registry <URL> --token <T>. For multiple targets in one go, set lpm.json > publish.registries — see lpm.json.
Common pitfalls
init -ydefaults aren't directory-derived. Under-y, the target is the LPM.dev Registry, owner is yourlpm whoamiprofile username (or the literal"username"if offline / not logged in), and name is literally"package"(not your directory's name). The published shape becomes@lpm.dev/<your-username>.package— pass--owner/--nameor edit before publishing.- Quality score below 80 by default = no readme, no license, no types. Easy fix; usually a 5-minute task.
- Distribution mode is irreversible. Pool / marketplace are one-way doors. Stay private until you're sure.
- Generated provenance only works in OIDC-capable CI. Don't pass
--provenancefrom a developer laptop. For npm-compatible targets with a pre-generated bundle, use--provenance-file <PATH>.
See also
lpm publish— full flag referencelpm quality— what the score coverslpm init— manifest scaffolding- Authentication — token management