NuGet is a package manager for the .NET ecosystem and is the primary way developers discover and acquire .NET open-source libraries. NuGet.org, a free service provided by Microsoft for hosting NuGet packages, is the primary host for public NuGet packages, but you can publish to custom NuGet services like MyGet and Azure Artifacts.
Create a NuGet package
A NuGet package (
*.nupkg) is a zip file that contains .NET assemblies and associated metadata.
There are two main ways to create a NuGet package. The newer and recommended way is to create a package from a SDK-style project (project file whose content starts with
<Project Sdk="Microsoft.NET.Sdk">). Assemblies and targets are automatically added to the package and remaining metadata is added to the MSBuild file, like package name and version number. Compiling with the
dotnet pack command outputs a
*.nupkg file instead of assemblies.
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> <AssemblyName>Contoso.Api</AssemblyName> <PackageVersion>1.1.0</PackageVersion> <Authors>John Doe</Authors> </PropertyGroup> </Project>
The older way of creating a NuGet package is with a
*.nuspec file and the
nuget.exe command-line tool. A nuspec file gives you great control but you must carefully specify what assemblies and targets to include in the final NuGet package. It's easy to make a mistake or for someone to forget to update the nuspec when making changes. The advantage of a nuspec is you can use it create NuGet packages for frameworks that don't yet support an SDK-style project file.
✔️ CONSIDER using an SDK-style project file to create the NuGet package.
NuGet package dependencies are covered in detail in the Dependencies article.
Important NuGet package metadata
A NuGet package supports many metadata properties. The following table contains the core metadata that every package on NuGet.org should provide:
|MSBuild Property name||Nuspec name||Description|
||The package identifier. A prefix from the identifier can be reserved if it meets the criteria.|
||NuGet package version. For more information, see NuGet package version.|
||A human-friendly title of the package. It defaults to the
||A long description of the package displayed in UI.|
||A comma-separated list of package authors, matching the profile names on nuget.org.|
||A space-delimited list of tags and keywords that describe the package. Tags are used when searching for packages.|
||A URL for an image to use as the icon for the package. URL should be HTTPS and the image should be 64x64 and have a transparent background.|
||A URL for the project homepage or source repository.|
||The project license's SPDX identifier. Only OSI and FSF approved licenses can use an identifier. Other licenses should use
A project without a license defaults to exclusive copyright, making it legally impossible for other people to use.
✔️ CONSIDER choosing a NuGet package name with a prefix that meets NuGet's prefix reservation criteria.
✔️ DO use an HTTPS href to your package icon.
Sites like NuGet.org run with HTTPS enabled and displaying a non-HTTPS image will create a mixed content warning.
✔️ DO use a package icon image that is 64x64 and has a transparent background for best viewing results.
✔️ CONSIDER setting up SourceLink to add source control metadata to your assemblies and NuGet package.
SourceLink automatically adds
RepositoryTypemetadata to the NuGet package. SourceLink also adds information about the exact source code the package was built from. For example, a package created from a Git repository will have the commit hash added as metadata.
NuGet packages with a version suffix are considered pre-release. By default, the NuGet Package Manager UI shows stable releases unless a user opts-in to pre-release packages, making pre-release packages ideal for limited user testing.
A stable package cannot depend on a pre-release package. You must either make your own package pre-release or depend on an older stable version.
✔️ DO publish a pre-release package when testing, previewing, or experimenting.
✔️ DO publish a stable package when its ready so other stable packages can reference it.
Symbol files (
*.pdb) are produced by the .NET compiler alongside assemblies. Symbol files map execution locations to the original source code so you can step through source code as it is running using a debugger. NuGet supports generating a separate symbol package (
*.snupkg) containing symbol files alongside the main package containing .NET assemblies. The idea of symbol packages is they're hosted on a symbol server and are only downloaded by a tool like Visual Studio on demand.
NuGet.org hosts its own symbols server repository. Developers can use the symbols published to the NuGet.org symbol server by adding
https://symbols.nuget.org/download/symbols to their symbol sources in Visual Studio.
The NuGet.org symbol server only supports the new portable symbol files (
*.pdb) created by SDK-style projects.
To use the NuGet.org symbol server when debugging a .NET library, developers must have Visual Studio 2017 15.9 or later.
An alternative to creating a symbol package is embedding symbol files in the main NuGet package. The main NuGet package will be larger, but the embedded symbol files means developers don't need to configure the NuGet.org symbol server. If you're building your NuGet package using an SDK-style project, then you can embed symbol files by setting the
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <!-- Include symbol files (*.pdb) in the built .nupkg --> <AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder> </PropertyGroup> </Project>
✔️ CONSIDER embedding symbol files in the main NuGet package.
Embedding symbol files in the main NuGet package gives developers a better debugging experience by default. They don't need to find and configure the NuGet symbol server in their IDE to get symbol files.
The downside to embedded symbol files is they increase the package size by about 30% for .NET libraries compiled using SDK-style projects. If package size is a concern, you should publish symbols in a symbol package instead.