en

Quick start

From zero to a restored project, in three commands.

This walkthrough takes you from a fresh checkout of a .NET project to a fully restored workspace that PCPM can manage, in three commands.

0. Assumptions

  • You have a .NET project or solution in the current directory.
  • PCPM is on your PATH (see Installation).
  • You’re on Windows, macOS, or Linux with the .NET 10 SDK.

1. Initialise or migrate the workspace

If you have an existing solution:

pcpm convert

PCPM walks every .csproj, hoists every per-project Version= into a <PackageVersion />, adopts your existing Directory.Packages.props if you have one, and writes pcpm.json + pcpm.lock. pcpm install runs at the end of the convert. --dry-run previews the diff; --revert undoes it.

If you’re starting from scratch:

pcpm init

PCPM looks for a .sln or .csproj at the current directory (or one level up) and creates three files if they don’t exist:

  • pcpm.json — PCPM’s own manifest. Tracks the store path, update preferences, and feature flags. You rarely edit this by hand.
  • Directory.Packages.props — Microsoft’s CPM file. PCPM writes <PackageVersion /> entries here when you run pcpm add.
  • pcpm-workspace.yaml (only for monorepos) — the project discovery configuration. Not created for single-project workspaces.

If you already have Directory.Packages.props (i.e. you were already using CPM), PCPM adopts it instead of overwriting.

Tip: pcpm init --help lists every option. The most useful are --no-cpm (don’t touch Directory.Packages.props) and --force (overwrite existing files).

2. Add your dependencies

pcpm add Microsoft.Extensions.Hosting
pcpm add Serilog
pcpm add Serilog.Sinks.Console

pcpm add does four things:

  1. Queries the feed for the latest stable version.
  2. Writes the version to Directory.Packages.props as a <PackageVersion />.
  3. Adds a <PackageReference Include="…" /> to every .csproj that references the project you ran from.
  4. Runs pcpm install (unless you pass --no-install).

The implicit install is a feature, not a bug — by the time your shell prompt comes back, the new dependency is on disk and ready to use.

3. Restore

If you skipped the implicit install in step 2, or if someone else just checked in a pcpm.lock change:

pcpm install

This is the workhorse command. It:

  1. Resolves the full transitive graph.
  2. Downloads every missing package into the global store (or hardlinks it from the store if it’s already there).
  3. Hardlinks each package from the store into ~/.nuget/packages.
  4. Runs dotnet restore against the materialised layout.

The first run downloads everything. Subsequent runs are near-instant — most packages come from the store, and dotnet restore only re-checks the lockfile.

4. Sanity check and inspect

pcpm list                  # pretty-prints pcpm.lock
pcpm why Serilog           # who pulled Serilog in
pcpm doctor                # CPM, lockfile, CVE, orphans
pcpm audit                 # vulnerabilities + licenses + SBOM
  • pcpm list prints the lockfile as a table. You should see your direct dependencies, plus their transitive graph, with resolved versions.
  • pcpm why Serilog shows the chain of dependents that pulled Serilog into the lockfile. Useful when a transitive update surprises you.
  • pcpm doctor runs the full CPM hygiene check (see Introduction). Wire this into your CI.
  • pcpm audit produces a vulnerability report, a license report, and an SBOM in one pass.

5. CI

Replace dotnet restore on your build server with:

pcpm ci

pcpm ci validates that pcpm.lock is in sync with the workspace, that every entry’s sha256 is present in the store, and then runs dotnet restore. It exits non-zero on the first inconsistency — a clean CI run that resolves a new transitive is now a build failure, not a silent regression.

What’s next