Create a NuGet package using the dotnet CLI
No matter what your package does or what code it contains, you use one of the CLI tools, either
dotnet.exe, to package that functionality into a component that can be shared with and used by any number of other developers. This article describes how to create a package using the dotnet CLI. To install the
dotnet CLI, see Install NuGet client tools. Starting in Visual Studio 2017, the dotnet CLI is included with .NET Core workloads.
For .NET Core and .NET Standard projects that use the SDK-style format, and any other SDK-style projects, NuGet uses information in the project file directly to create a package. For step-by-step tutorials, see Create .NET Standard Packages with dotnet CLI or Create .NET Standard Packages with Visual Studio.
msbuild -t:pack is functionality equivalent to
dotnet pack. To build with MSBuild, see Create a NuGet package using MSBuild.
This topic applies to SDK-style projects, typically .NET Core and .NET Standard projects.
The following properties are required to create a package.
PackageId, the package identifier, which must be unique across the gallery that hosts the package. If not specified, the default value is
Version, a specific version number in the form Major.Minor.Patch[-Suffix] where -Suffix identifies pre-release versions. If not specified, the default value is 1.0.0.
- The package title as it should appear on the host (like nuget.org)
Authors, author and owner information. If not specified, the default value is
Company, your company name. If not specified, the default value is
In Visual Studio, you can set these values in the project properties (right-click the project in Solution Explorer, choose Properties, and select the Package tab). You can also set these properties directly in the project files (
<PropertyGroup> <PackageId>AppLogger</PackageId> <Version>1.0.0</Version> <Authors>your_name</Authors> <Company>your_company</Company> </PropertyGroup>
Give the package an identifier that's unique across nuget.org or whatever package source you're using.
The following example shows a simple, complete project file with these properties included. (You can create a new default project using the
dotnet new classlib command.)
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> <PackageId>AppLogger</PackageId> <Version>1.0.0</Version> <Authors>your_name</Authors> <Company>your_company</Company> </PropertyGroup> </Project>
For packages built for public consumption, pay special attention to the PackageTags property, as tags help others find your package and understand what it does.
For details on declaring dependencies and specifying version numbers, see Package references in project files and Package versioning. It is also possible to surface assets from dependencies directly in the package by using the
<ExcludeAssets> attributes. For more information, seee Controlling dependency assets.
Add an optional description field
The package's optional description, displayed on the package's NuGet.org page, is either pulled in from the
<description></description> used in the
.csproj file or pulled in via the
$description in the .nuspec file.
An example of a description field is shown in the following XML text of the
.csproj file for a .NET package:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <PackageId>Azure.Storage.Blobs</PackageId> <Version>12.4.0</Version> <PackageTags>Microsoft Azure Storage Blobs;Microsoft;Azure;Blobs;Blob;Storage;StorageScalable</PackageTags> <Description> This client library enables working with the Microsoft Azure Storage Blob service for storing binary and text data. For this release see notes - https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Azure.Storage.Blobs/README.md and https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Azure.Storage.Blobs/CHANGELOG.md in addition to the breaking changes https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Azure.Storage.Blobs/BreakingChanges.txt Microsoft Azure Storage quickstarts and tutorials - https://docs.microsoft.com/en-us/azure/storage/ Microsoft Azure Storage REST API Reference - https://docs.microsoft.com/en-us/rest/api/storageservices/ REST API Reference for Blob Service - https://docs.microsoft.com/en-us/rest/api/storageservices/blob-service-rest-api </Description> </PropertyGroup> </PropertyGroup>
Choose a unique package identifier and set the version number
The package identifier and the version number are the two most important values in the project because they uniquely identify the exact code that's contained in the package.
Best practices for the package identifier:
- Uniqueness: The identifier must be unique across nuget.org or whatever gallery hosts the package. Before deciding on an identifier, search the applicable gallery to check if the name is already in use. To avoid conflicts, a good pattern is to use your company name as the first part of the identifier, such as
- Namespace-like names: Follow a pattern similar to namespaces in .NET, using dot notation instead of hyphens. For example, use
Contoso_Utility_UsefulStuff. Consumers also find it helpful when the package identifier matches the namespaces used in the code.
- Sample Packages: If you produce a package of sample code that demonstrates how to use another package, attach
.Sampleas a suffix to the identifier, as in
Contoso.Utility.UsefulStuff.Sample. (The sample package would of course have a dependency on the other package.) When creating a sample package, use the
<IncludeAssets>. In the
contentfolder, arrange the sample code in a folder called
Best practices for the package version:
- In general, set the version of the package to match the project (or assembly), though this is not strictly required. This is a simple matter when you limit a package to a single assembly. Overall, remember that NuGet itself deals with package versions when resolving dependencies, not assembly versions.
- When using a non-standard version scheme, be sure to consider the NuGet versioning rules as explained in Package versioning. NuGet is mostly semver 2 compliant.
For information on dependency resolution, see Dependency resolution with PackageReference. For older information that may also be helpful to better understand versioning, see this series of blog posts.
Run the pack command
To build a NuGet package (a
.nupkg file) from the project, run the
dotnet pack command, which also builds the project automatically:
# Uses the project file in the current folder by default dotnet pack
The output shows the path to the
Microsoft (R) Build Engine version 126.96.36.199428 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restore completed in 29.91 ms for D:\proj\AppLoggerNet\AppLogger\AppLogger.csproj. AppLogger -> D:\proj\AppLoggerNet\AppLogger\bin\Debug\netstandard2.0\AppLogger.dll Successfully created package 'D:\proj\AppLoggerNet\AppLogger\bin\Debug\AppLogger.1.0.0.nupkg'.
Automatically generate package on build
To automatically run
dotnet pack when you run
dotnet build, add the following line to your project file within
When you automatically generate the package, the time to pack increases the build time for your project.
Test package installation
Before publishing a package, you typically want to test the process of installing a package into a project. The tests make sure that the necessarily files all end up in their correct places in the project.
You can test installations manually in Visual Studio or on the command line using the normal package installation steps.
Packages are immutable. If you correct a problem, change the contents of the package and pack again, when you retest you will still be using the old version of the package until you clear your global packages folder. This is especially relevant when testing packages that don't use a unique prerelease label on every build.
Once you've created a package, which is a
.nupkg file, you can publish it to the gallery of your choice as described on Publishing a Package.
You might also want to extend the capabilities of your package or otherwise support other scenarios as described in the following topics:
- Package versioning
- Support multiple target frameworks
- Add a package icon
- Transformations of source and configuration files
- Pre-release versions
- Set package type
- Create packages with COM interop assemblies
Finally, there are additional package types to be aware of: