No matter what your package does or what code it contains, you use one of the CLI tools, either nuget.exe
or dotnet.exe
, to package that functionality into a component that can be shared with and used by any number of other developers. To install NuGet CLI tools, see Install NuGet client tools. Note that Visual Studio does not automatically include a CLI tool.
For non-SDK-style projects, typically .NET Framework projects, follow the steps described in this article to create a package. For step-by-step instructions using Visual Studio and the nuget.exe
CLI, see Create and publish a .NET Framework package.
For .NET Core and .NET Standard projects that use the SDK-style format, and any other SDK-style projects, see Create a NuGet package using the dotnet CLI.
For projects migrated from packages.config
to PackageReference, use msbuild -t:pack.
Technically speaking, a NuGet package is just a ZIP file that's been renamed with the .nupkg
extension and whose contents match certain conventions. This topic describes the detailed process of creating a package that meets those conventions.
Packaging begins with the compiled code (assemblies), symbols, and/or other files that you want to deliver as a package (see Overview and workflow). This process is independent from compiling or otherwise generating the files that go into the package, although you can draw from information in a project file to keep the compiled assemblies and packages in sync.
Important
This topic applies to non-SDK-style projects, typically projects other than .NET Core and .NET Standard projects using Visual Studio 2017 and higher versions and NuGet 4.0+.
Decide which assemblies to packageMost general-purpose packages contain one or more assemblies that other developers can use in their own projects.
In general, it's best to have one assembly per NuGet package, provided that each assembly is independently useful. For example, if you have a Utilities.dll
that depends on Parser.dll
, and Parser.dll
is useful on its own, then create one package for each. Doing so allows developers to use Parser.dll
independently of Utilities.dll
.
If your library is composed of multiple assemblies that aren't independently useful, then it's fine to combine them into one package. Using the previous example, if Parser.dll
contains code that's used only by Utilities.dll
, then it's fine to keep Parser.dll
in the same package.
Similarly, if Utilities.dll
depends on Utilities.resources.dll
, where again the latter is not useful on its own, then put both in the same package.
Resources are, in fact, a special case. When a package is installed into a project, NuGet automatically adds assembly references to the package's DLLs, excluding those that are named .resources.dll
because they are assumed to be localized satellite assemblies (see Creating localized packages). For this reason, avoid using .resources.dll
for files that otherwise contain essential package code.
If your library contains COM interop assemblies, follow additional the guidelines in Create packages with COM interop assemblies.
The role and structure of the .nuspec fileOnce you know what files you want to package, the next step is creating a package manifest in a .nuspec
XML file.
The manifest:
Required properties:
Common optional properties:
licenseUrl
is deprecated, use license
nuspec metadata element instead)iconUrl
is deprecated use icon
nuspec metadata element instead)The following is a typical (but fictitious) .nuspec
file, with comments describing the properties:
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<!-- Identifier that must be unique within the hosting gallery -->
<id>Contoso.Utility.UsefulStuff</id>
<!-- Package version number that is used when resolving dependencies -->
<version>1.8.3</version>
<!-- Authors contain text that appears directly on the gallery -->
<authors>Dejana Tesic, Rajeev Dey</authors>
<!--
Owners are typically nuget.org identities that allow gallery
users to easily find other packages by the same owners.
-->
<owners>dejanatc, rjdey</owners>
<!-- Project URL provides a link for the gallery -->
<projectUrl>http://github.com/contoso/UsefulStuff</projectUrl>
<!-- License information is displayed on the gallery -->
<license type="expression">Apache-2.0</license>
<!-- Icon is used in Visual Studio's package manager UI -->
<icon>icon.png</icon>
<!--
If true, this value prompts the user to accept the license when
installing the package.
-->
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<!-- Any details about this particular release -->
<releaseNotes>Bug fixes and performance improvements</releaseNotes>
<!--
The description can be used in package manager UI. Note that the
nuget.org gallery uses information you add in the portal.
-->
<description>Core utility functions for web applications</description>
<!-- Copyright information -->
<copyright>Copyright ©2016 Contoso Corporation</copyright>
<!-- Tags appear in the gallery and can be used for tag searches -->
<tags>web utility http json url parsing</tags>
<!-- Dependencies are automatically installed when the package is installed -->
<dependencies>
<dependency id="Newtonsoft.Json" version="9.0" />
</dependencies>
</metadata>
<!-- A readme.txt to display when the package is installed -->
<files>
<file src="readme.txt" target="" />
<file src="icon.png" target="" />
</files>
</package>
For details on declaring dependencies and specifying version numbers, see packages.config and Package versioning. It is also possible to surface assets from dependencies directly in the package by using the include
and exclude
attributes on the dependency
element. See .nuspec Reference - Dependencies.
Because the manifest is included in the package created from it, you can find any number of additional examples by examining existing packages. A good source is the global-packages folder on your computer, the location of which is returned by the following command:
nuget locals -list global-packages
Go into any package\version folder, copy the .nupkg
file to a .zip
file, then open that .zip
file and examine the .nuspec
within it.
Creating a complete manifest typically begins with a basic .nuspec
file generated through one of the following methods:
You then edit the file by hand so that it describes the exact content you want in the final package.
Important
Generated .nuspec
files contain placeholders that must be modified before creating the package with the nuget pack
command. That command fails if the .nuspec
contains any placeholders.
Because a NuGet package is just a ZIP file that's been renamed with the .nupkg
extension, it's often easiest to create the folder structure you want on your local file system, then create the .nuspec
file directly from that structure. The nuget pack
command then automatically adds all files in that folder structure (excluding any folders that begin with .
, allowing you to keep private files in the same structure).
The advantage to this approach is that you don't need to specify in the manifest which files you want to include in the package (as explained later in this topic). You can simply have your build process produce the exact folder structure that goes into the package, and you can easily include other files that might not be part of a project otherwise:
The folder conventions are as follows:
Folder Description Action upon package install (root) Location for readme.txt Visual Studio displays a readme.txt file in the package root when the package is installed. lib/{tfm} Assembly (.dll
), documentation (.xml
), and symbol (.pdb
) files for the given Target Framework Moniker (TFM) Assemblies are added as references for compile as well as runtime; .xml
and .pdb
copied into project folders. See Supporting multiple target frameworks for creating framework target-specific sub-folders. ref/{tfm} Assembly (.dll
), and symbol (.pdb
) files for the given Target Framework Moniker (TFM) Assemblies are added as references only for compile time; So nothing will be copied into project bin folder. runtimes Architecture-specific assembly (.dll
), symbol (.pdb
), and native resource (.pri
) files Assemblies are added as references only for runtime; other files are copied into project folders. There should always be a corresponding (TFM) AnyCPU
specific assembly under /ref/{tfm}
folder to provide corresponding compile time assembly. See Supporting multiple target frameworks. content Arbitrary files Contents are copied to the project root. Think of the content folder as the root of the target application that ultimately consumes the package. To have the package add an image in the application's /images folder, place it in the package's content/images folder. build (3.x+) MSBuild .targets
and .props
files Automatically inserted into the project. buildMultiTargeting (4.0+) MSBuild .targets
and .props
files for cross-framework targeting Automatically inserted into the project. buildTransitive (5.0+) MSBuild .targets
and .props
files that flow transitively to any consuming project. See the feature page. Automatically inserted into the project. tools Powershell scripts and programs accessible from the Package Manager Console The tools
folder is added to the PATH
environment variable for the Package Manager Console only (Specifically, not to the PATH
as set for MSBuild when building the project).
Because your folder structure can contain any number of assemblies for any number of target frameworks, this method is necessary when creating packages that support multiple frameworks.
In any case, once you have the desired folder structure in place, run the following command in that folder to create the .nuspec
file:
nuget spec
Again, the generated .nuspec
contains no explicit references to files in the folder structure. NuGet automatically includes all files when the package is created. You still need to edit placeholder values in other parts of the manifest, however.
In the simple case of creating a package from an assembly, you can generate a .nuspec
file from the metadata in the assembly using the following command:
nuget spec <assembly-name>.dll
Using this form replaces a few placeholders in the manifest with specific values from the assembly. For example, the <id>
property is set to the assembly name, and <version>
is set to the assembly version. Other properties in the manifest, however, don't have matching values in the assembly and thus still contain placeholders.
Creating a .nuspec
from a .csproj
or .vbproj
file is convenient because other packages that have been installed into those project are automatically referenced as dependencies. Simply use the following command in the same folder as the project file:
# Use in a folder containing a project file <project-name>.csproj or <project-name>.vbproj
nuget spec
The resulting <project-name>.nuspec
file contains tokens that are replaced at packaging time with values from the project, including references to any other packages that have already been installed.
If you have package dependencies to include in the .nuspec, instead use nuget pack
, and get the .nuspec file from within the generated .nupkg file. For example, use the following command.
# Use in a folder containing a project file <project-name>.csproj or <project-name>.vbproj
nuget pack myproject.csproj
A token is delimited by $
symbols on both sides of the project property. For example, the <id>
value in a manifest generated in this way typically appears as follows:
<id>$id$</id>
This token is replaced with the AssemblyName
value from the project file at packing time. For the exact mapping of project values to .nuspec
tokens, see the Replacement Tokens reference.
Tokens relieve you from needing to update crucial values like the version number in the .nuspec
as you update the project. (You can always replace the tokens with literal values, if desired).
Note that there are several additional packaging options available when working from a Visual Studio project, as described in Running nuget pack to generate the .nupkg file later on.
Solution-level packagesNuGet 2.x only. Not available in NuGet 3.0+.
NuGet 2.x supported the notion of a solution-level package that installs tools or additional commands for the Package Manager Console (the contents of the tools
folder), but does not add references, content, or build customizations to any projects in the solution. Such packages contain no files in its direct lib
, content
, or build
folders, and none of its dependencies have files in their respective lib
, content
, or build
folders.
NuGet tracks installed solution-level packages in a packages.config
file in the .nuget
folder, rather than the project's packages.config
file.
The following command creates a default manifest with placeholders, which ensures you start with the proper file structure:
nuget spec [<package-name>]
If you omit <package-name>, the resulting file is Package.nuspec
. If you provide a name such as Contoso.Utility.UsefulStuff
, the file is Contoso.Utility.UsefulStuff.nuspec
.
The resulting .nuspec
contains placeholders for values like the projectUrl
. Be sure to edit the file before using it to create the final .nupkg
file.
The package identifier (<id>
element) and the version number (<version>
element) are the two most important values in the manifest because they uniquely identify the exact code that's contained in the package.
Best practices for the package identifier:
Contoso.
.Contoso.Utility.UsefulStuff
rather than Contoso-Utility-UsefulStuff
or Contoso_Utility_UsefulStuff
. Consumers also find it helpful when the package identifier matches the namespaces used in the code..Sample
as 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 convention-based working directory method described earlier. In the content
folder, arrange the sample code in a folder called \Samples\<identifier>
as in \Samples\Contoso.Utility.UsefulStuff.Sample
.Best practices for the package version:
Add a readme and other filesThe following series of brief blog posts are also helpful to understand versioning:
To directly specify files to include in the package, use the <files>
node in the .nuspec
file, which follows the <metadata>
tag:
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<!-- ... -->
</metadata>
<files>
<!-- Add a readme -->
<file src="readme.txt" target="" />
<!-- Add files from an arbitrary folder that's not necessarily in the project -->
<file src="..\..\SomeRoot\**\*.*" target="" />
</files>
</package>
Tip
When using the convention-based working directory approach, you can place the readme.txt in the package root and other content in the content
folder. No <file>
elements are necessary in the manifest.
When you include a file named readme.txt
in the package root, Visual Studio displays the contents of that file as plain text immediately after installing the package directly. (Readme files are not displayed for packages installed as dependencies). For example, here's how the readme for the HtmlAgilityPack package appears:
Note
If you include an empty <files>
node in the .nuspec
file, NuGet doesn't include any other content in the package other than what's in the lib
folder.
In some cases, you might want to add custom build targets or properties in projects that consume your package, such as running a custom tool or process during build. You can learn more about MSBuild props and targets in NuGet packages
Create <package_id>.targets
or <package_id>.props
(such as Contoso.Utility.UsefulStuff.targets
) within the build folders of the project.
Then in the .nuspec
file, be sure to refer to these files in the <files>
node:
<?xml version="1.0"?>
<package >
<metadata minClientVersion="2.5">
<!-- ... -->
</metadata>
<files>
<!-- Include everything in \build -->
<file src="build\**" target="build" />
<!-- Other files -->
<!-- ... -->
</files>
</package>
When packages are added to a project, NuGet will automatically include these props and targets.
Run nuget pack to generate the .nupkg fileWhen using an assembly or the convention-based working directory, create a package by running nuget pack
with your .nuspec
file, replacing <project-name>
with your specific filename:
nuget pack <project-name>.nuspec
When using a Visual Studio project, run nuget pack
with your project file, which automatically loads the project's .nuspec
file and replaces any tokens within it using values in the project file:
nuget pack <project-name>.csproj
Note
Using the project file directly is necessary for token replacement because the project is the source of the token values. Token replacement does not happen if you use nuget pack
with a .nuspec
file.
In all cases, nuget pack
excludes folders that start with a period, such as .git
or .hg
.
NuGet indicates if there are any errors in the .nuspec
file that need correcting, such as forgetting to change placeholder values in the manifest.
Once nuget pack
succeeds, you have a .nupkg
file that you can publish to a suitable gallery as described in Publishing a Package.
Tip
A helpful way to examine a package after creating it is to open it in the Package Explorer tool. This gives you a graphical view of the package contents and its manifest. You can also rename the resulting .nupkg
file to a .zip
file and explore its contents directly.
You can use various command-line switches with nuget pack
to exclude files, override the version number in the manifest, and change the output folder, among other features. For a complete list, refer to the pack command reference.
The following options are a few that are common with Visual Studio projects:
Referenced projects: If the project references other projects, you can add the referenced projects as part of the package, or as dependencies, by using the -IncludeReferencedProjects
option:
nuget pack MyProject.csproj -IncludeReferencedProjects
This inclusion process is recursive, so if MyProject.csproj
references projects B and C, and those projects reference D, E, and F, then files from B, C, D, E, and F are included in the package.
If a referenced project includes a .nuspec
file of its own, then NuGet adds that referenced project as a dependency instead. You need to package and publish that project separately.
Build configuration: By default, NuGet uses the default build configuration set in the project file, typically Debug. To pack files from a different build configuration, such as Release, use the -properties
option with the configuration:
nuget pack MyProject.csproj -properties Configuration=Release
Symbols: to include symbols that allow consumers to step through your package code in the debugger, use the -Symbols
option:
nuget pack MyProject.csproj -symbols
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.
For automated testing, the basic process is as follows:
.nupkg
file to a local folder.nuget sources add -name <name> -source <path>
command (see nuget sources). Note that you need only set this local source once on any given computer.nuget install <packageID> -source <name>
where <name>
matches the name of your source as given to nuget sources
. Specifying the source ensures that the package is installed from that source alone.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:
Finally, there are additional package types to be aware of:
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4