dotnet-pack(1)

πŸ“¦
version 11.0.0~rc3 Β· 6 versions
, in alpine 3.24, centos-stream 10, centos-stream 9, fedora 43, fedora 44, nixpkgs unstable, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking

okay so bestie, you've found the manual page for dotnet-pack(1) πŸ’– β€” that's the .NET Documentation one, and yes, this article applies to: βœ”οΈ .NET 6 SDK and later versions. Strap in, she's a long one. 🌸


πŸŽ€ NAME πŸŽ€

dotnet-pack β€” Packs the code into a NuGet package. that's it. that's the vibe. πŸ’…


✨ SYNOPSIS ✨

dotnet pack [<PROJECT>|<SOLUTION>]
  [--artifacts-path <ARTIFACTS_DIR>] [-c|--configuration <CONFIGURATION>]
  [--disable-build-servers] [--force] [--include-source] [--include-symbols]
  [--interactive] [--no-build] [--no-dependencies] [--no-restore] [--nologo]
  [-o|--output <OUTPUT_DIRECTORY>] [--runtime <RUNTIME_IDENTIFIER>]
  [-s|--serviceable] [--tl:[auto|on|off]] [-v|--verbosity <LEVEL>]
  [--version-suffix <VERSION_SUFFIX>]

dotnet pack -h|--help

🌈 DESCRIPTION 🌈

okay so the dotnet pack command builds the project and creates NuGet packages. what you get out of it is a NuGet package β€” that is, a .nupkg file. periodt. πŸ’…

if you want to generate a package that has the debug symbols in it too, you've got two options, bestie:

  • --include-symbols β€” it creates the symbols package.
  • --include-source β€” it creates the symbols package with a src folder inside containing the source files.

NuGet dependencies of the packed project get added to the .nuspec file, so they're properly resolved when the package gets installed. but listen β€” if the packed project has references to other projects, those other projects aren't included in the package. 😭 Currently, you must have a package per project if you have project-to-project dependencies.

By default, dotnet pack builds the project first. if you wish to avoid this behavior, pass the --no-build option. this option is often useful in Continuous Integration (CI) build scenarios where you know the code was previously built. ✨

πŸ™ˆ In some cases, the implicit build cannot be performed. This can occur when GeneratePackageOnBuild is set, to avoid a cyclic dependency between build and pack targets. The build can also fail if there is a locked file or other issue.

you can provide MSBuild properties to the dotnet pack command for the packing process. for more information, see NuGet pack target properties and the MSBuild Command-Line Reference. the Examples section shows how to use the MSBuild -p switch for a couple of different scenarios. πŸ‘‘

⚠️ Web projects aren't packable. (not me finding that out the hard way πŸ’€)

πŸ¦‹ Implicit restore πŸ¦‹

you don't have to run dotnet restore because it's run implicitly by all commands that require a restore to occur β€” like dotnet new, dotnet build, dotnet run, dotnet test, dotnet publish, and dotnet pack. to disable implicit restore, use the --no-restore option. 🫢

the dotnet restore command is still useful in certain scenarios where explicitly restoring makes sense, such as continuous integration builds in Azure DevOps Services or in build systems that need to explicitly control when the restore occurs.

for info about how to manage NuGet feeds, see the dotnet restore documentation.

πŸ’‘ This command supports the dotnet restore options when passed in the long form (for example, --source). Short form options, such as -s, are not supported. iykyk.

🧚 Workload manifest downloads 🧚

when you run this command, it initiates an asynchronous background download of advertising manifests for workloads. if the download is still running when this command finishes, the download is stopped. for more information, see Advertising manifests.


🌸 ARGUMENTS 🌸

  • PROJECT | SOLUTION β€” the project or solution to pack. it's either a path to a csproj, vbproj, or fsproj file, or to a solution file or directory. if not specified, the command searches the current directory for a project or solution file. πŸŽ€

πŸ‘‘ OPTIONS πŸ‘‘

  • --artifacts-path <ARTIFACTS_DIR> β€” all build output files from the executed command will go in subfolders under the specified path, separated by project. for more information see Artifacts Output Layout. available since .NET 8 SDK. ✨
  • -c|--configuration <CONFIGURATION> β€” defines the build configuration. if you're developing with the .NET 8 SDK or a later version, the command uses the Release configuration by default for projects whose TargetFramework is set to net8.0 or a later version. the default build configuration is Debug for earlier versions of the SDK and for earlier target frameworks. you can override the default in project settings or by using this option. for more info, see dotnet publish uses Release configuration and dotnet pack uses Release configuration. πŸ’…
  • --disable-build-servers β€” forces the command to ignore any persistent build servers. this option provides a consistent way to disable all use of build caching, which forces a build from scratch. a build that doesn't rely on caches is useful when the caches might be corrupted or incorrect for some reason. available since .NET 7 SDK. πŸ”₯
  • --force β€” forces all dependencies to be resolved even if the last restore was successful. specifying this flag is the same as deleting the project.assets.json file. πŸ’€
  • --include-source β€” includes the debug symbols NuGet packages in addition to the regular NuGet packages in the output directory. the sources files are included in the src folder within the symbols package.
  • --include-symbols β€” includes the debug symbols NuGet packages in addition to the regular NuGet packages in the output directory.
  • --interactive β€” allows the command to stop and wait for user input or action. for example, to complete authentication. πŸ™ˆ
  • --no-build β€” doesn't build the project before packing. it also implicitly sets the --no-restore flag.
  • --no-dependencies β€” ignores project-to-project references and only restores the root project.
  • --no-restore β€” doesn't execute an implicit restore when running the command.
  • --nologo β€” doesn't display the startup banner or the copyright message. (lowkey the move for clean CI logs 🧼)
  • -o|--output <OUTPUT_DIRECTORY> β€” places the built packages in the directory specified.
    • .NET 7.0.200 SDK β€” in the 7.0.200 SDK, if you specify the --output option when running this command on a solution, the CLI will emit an error. this is a regression and was fixed in 7.0.201 and later versions of the .NET SDK. 😭
  • --runtime <RUNTIME_IDENTIFIER> β€” specifies the target runtime to restore packages for. for a list of Runtime Identifiers (RIDs), see the RID catalog.
  • -s|--serviceable β€” sets the serviceable flag in the package. for more information, see .NET Blog: .NET Framework 4.5.1 Supports Microsoft Security Updates for .NET NuGet Libraries (https://aka.ms/nupkgservicing). πŸŽ€
  • --tl:[auto|on|off] β€” specifies whether Terminal Logger should be used for the build output. the default is auto, which first verifies the environment before enabling terminal logging. the environment check verifies that the terminal is capable of using modern output features and isn't using a redirected standard output before enabling the new logger. on skips the environment check and enables terminal logging. off skips the environment check and uses the default console logger.

Terminal Logger shows you the restore phase followed by the build phase. during each phase, the currently building projects appear at the bottom of the terminal. each project that's building outputs both the MSBuild target currently being built and the amount of time spent on that target. you can search this information to learn more about the build. when a project is finished building, a single "build completed" section is written that captures:

  • The name of the built project.
  • The target framework (if multi-targeted).
  • The status of that build.
  • The primary output of that build (which is hyperlinked).
  • Any diagnostics generated for that project.
πŸ’œ This option is available starting in .NET 8.
  • -v|--verbosity <LEVEL> β€” sets the verbosity level of the command. allowed values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]. for more information, see <xref:Microsoft.Build.Framework.LoggerVerbosity>. 🌈
  • --version-suffix <VERSION_SUFFIX> β€” defines the value for the VersionSuffix MSBuild property. the effect of this property on the package version depends on the values of the Version and VersionPrefix properties, like this:
    • no properties with values β†’ package version 1.0.0
    • Version β†’ package version $(Version)
    • VersionPrefix only β†’ package version $(VersionPrefix)
    • VersionSuffix only β†’ package version 1.0.0-$(VersionSuffix)
    • VersionPrefix and VersionSuffix β†’ package version $(VersionPrefix)-$(VersionSuffix)

if you want to use --version-suffix, specify VersionPrefix and not Version in the project file. for example, if VersionPrefix is 0.1.2 and you pass --version-suffix rc.1 to dotnet pack, the package version will be 0.1.2-rc.1. ✨

πŸ™ˆ If Version has a value and you pass --version-suffix to dotnet pack, the value specified for --version-suffix is ignored.
  • -?|-h|--help β€” prints out a description of how to use the command. 🫢

✨ EXAMPLES ✨

okay bestie this is the part where it all clicks, like the vibes are immaculate here πŸ’… every single one of these is copy-paste-able, no cap.


πŸŽ€ the classics

  • Pack the project in the current directory:
dotnet pack

literally the bare minimum and she still ate πŸ”₯

  • Pack the app1 project:
dotnet pack ~/projects/app1/project.csproj

point at the project file directly when you're not standing in it, iykyk 🫢

  • Pack the project in the current directory and place the resulting packages into the nupkgs folder:
dotnet pack --output nupkgs
  • Pack the project in the current directory into the nupkgs folder and skip the build step:
dotnet pack --no-build --output nupkgs

no build, just vibes ✨


πŸ¦‹ versioning shenanigans

  • With the project's version suffix configured as <VersionSuffix>$(VersionSuffix)</VersionSuffix> in the .csproj file, pack the current project and update the resulting package version with the given suffix:
dotnet pack --version-suffix "ci-1234"
  • Set the package version to 2.1.0 with the PackageVersion MSBuild property:
dotnet pack -p:PackageVersion=2.1.0

🌸 targeting & runtime things

  • Pack the project for a specific target framework:
dotnet pack -p:TargetFrameworks=net45
  • Pack the project and use a specific runtime (Windows) for the restore operation:
dotnet pack --runtime win-x64

🧚 the nuspec era

  • Pack the project using a .nuspec file:
dotnet pack ~/projects/app1/project.csproj -p:NuspecFile=~/projects/app1/project.nuspec -p:NuspecBasePath=~/projects/app1/nuget

For information about how to use NuspecFile, NuspecBasePath, and NuspecProperties, see the following resources:

  • Packing using a .nuspec
  • Advanced extension points to create customized package
  • Global properties
fr fr go read those three, they're the main character energy of nuspec packing πŸ‘‘

and that's the whole page bestie!! πŸ’– this one came from the dotnet-pack(1) man page, dated 2025-10-30 β€” go forth and pack, you absolute icon πŸŽ€βœ¨πŸ¦‹

πŸ“¦ where this page comes from