Skip to content

/commands/nuget/dotnet-pack-create-nuget-package

dotnet pack: create a NuGet package (.nupkg) from a project

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
NuGet
versions
.NET 8, .NET 9, .NET 10
os
linux, macos, windows

dotnet pack -c Release -o nupkgs builds the project and writes a NuGet package, PackageId.Version.nupkg, into the nupkgs folder. The package id defaults to the project name and the version to 1.0.0; set PackageId, Version, Authors, Description and other metadata in the project file, or override the version per build with -p:Version=1.2.3. Upload the result with dotnet nuget push.

Pack a library

bash
dotnet new classlib -o Acme.Text > /dev/null
cd Acme.Text
dotnet pack -c Release -o ../nupkgs -v q --nologo > /dev/null
dotnet pack -c Release -o ../nupkgs -v q --nologo -p:Version=1.2.3 > /dev/null
ls ../nupkgs
unzip -l ../nupkgs/Acme.Text.1.2.3.nupkg | grep -oE "lib/[^ ]+\.dll|Acme\.Text\.nuspec"

Output

Acme.Text.1.0.0.nupkg
Acme.Text.1.2.3.nupkg
Acme.Text.nuspec
lib/net10.0/Acme.Text.dll

The first run produced the default 1.0.0, the second used the version passed on the command line. A .nupkg is a zip file, so unzip -l lists it: it contains the compiled DLL under lib/TARGET-FRAMEWORK/ and a generated .nuspec manifest with the metadata.

Metadata in the project file

Acme.Text.csproj
<PropertyGroup>
  <TargetFramework>net8.0</TargetFramework>
  <PackageId>Acme.Text</PackageId>
  <Version>1.2.3</Version>
  <Authors>Acme</Authors>
  <Description>Text helpers.</Description>
  <PackageLicenseExpression>MIT</PackageLicenseExpression>
  <PackageReadmeFile>README.md</PackageReadmeFile>
  <RepositoryUrl>https://github.com/acme/text</RepositoryUrl>
</PropertyGroup>
<ItemGroup>
  <None Include="README.md" Pack="true" PackagePath="\" />
</ItemGroup>

Options

CommandWhat it does
dotnet packRelease build (the default since .NET 8), package into bin/Release
dotnet pack -c Release -o nupkgsRelease build into the nupkgs folder
dotnet pack -p:Version=1.2.3Override the package version
dotnet pack --version-suffix beta.1With VersionPrefix 1.2.3 in the project, produce 1.2.3-beta.1
dotnet pack --include-symbols -p:SymbolPackageFormat=snupkgAlso create a .snupkg symbol package
dotnet pack --no-buildPackage an existing build (after dotnet build -c Release)
dotnet pack Shop.slnxEvery packable project of a solution
dotnet nuget push nupkgs/*.nupkg -s SOURCEUpload packages to a feed

Pitfalls

  • Same version twice. NuGet caches packages by id and version. Re-packing 1.0.0 with different code and installing it again on the same machine gives the old cached copy; bump the version or clear the cache with dotnet nuget locals.
  • Missing metadata warnings. Without Authors, Description or a license, pack still succeeds but prints NuGet pack warnings (NU5xxx codes); NuGet error codes explains the families.
  • Application projects. Packing a console app creates a library-style package unless you set PackAsTool (for a .NET tool); for programs, dotnet publish is usually what you want.
  • --version-suffix needs VersionPrefix. If the project sets Version directly, the suffix is ignored.

How to confirm it worked

ls nupkgs shows the .nupkg file with the expected id and version. Install it in another project from the local folder with dotnet add package Acme.Text --version 1.2.3 -s ../nupkgs and build that project.

FAQ

How do I test a package before publishing it?

Add the output folder as a local source, for example dotnet nuget add source ./nupkgs -n local, or pass -s ./nupkgs to dotnet add package in another project. NuGet caches packages by id and version, so bump the version (or clear the cache) after changing it.

How do I publish the package to nuget.org?

Use dotnet nuget push file.nupkg --source https://api.nuget.org/v3/index.json with an API key from your nuget.org account. Published versions cannot be overwritten, only unlisted.

Why does dotnet pack skip my test project?

Test project templates set IsPackable to false, so dotnet pack on a solution packs only the libraries. Set IsPackable to true in a project to include it.

Sources