We want to start this post with a huge thanks to you, the NuGet community. Over the last several months we have been talking to many of you to get feedback on NuGet package identity and trust. We’ve learned so much from you and we hope that what we have planned addresses some of the top concerns you have expressed to us.
One of the recurring messages we heard from you is that it is difficult to determine the origin of a package. More specifically, who produced and published the package that you want to use, and is that person or organization trustworthy?
We want to tackle this problem head on – read on to see what’s in store for our first feature to address NuGet package identity. We are still working on the finer details of the solution, so any feedback you have is greatly appreciated. Please leave a comment on this post or reach out to me (firstname.lastname@example.org) directly.
Below you can find a quick summary of the first problem we are trying to solve, and our proposed solution. Read past the summary to get into some of the nitty gritty details of both the problem and our first set of solutions.
Today, there are multiple properties that identify a NuGet package. Each property serves a purpose, but this sometimes makes it difficult as a NuGet package consumer to fully understand the source of a NuGet package. Ultimately, we’ve observed customers want to know who produced and published the package they are about to consume.
To empower NuGet package consumers to quickly identify that the packages they consume originates from a trusted package owner, we are introducing a concept known as verified package owners. This feature will be exclusive to accounts registered with nuget.org. When an account owner is verified, we will provide a visual indicator for NuGet package consumers to know if the packages they are consuming originate from package owners that have verified their identity with the nuget.org server administrators. This should give NuGet package consumers the ability to quickly identify the true source of their package.
In addition, verified package owners will have an opportunity to apply for a reserved package ID prefix. Only the owner that reserves a package ID prefix will be able to submit new packages that match the ID prefix glob pattern. For example, the .NET Foundation will manage the package prefix System.* – if you want to submit a package that matches the System.* naming pattern, you will first need to get permission from the .NET Foundation.
Based on your feedback, we realize there are several other areas of investment that we need to consider and prioritize over time. The verified package owner and reserved package ID prefix feature set is a tactical first investment to set us up for success in the future, and to empower NuGet package consumers with the information they need. As we continue to work on improving package identity, we want to make sure that we don’t negatively impact existing NuGet scenarios across all NuGet clients.
Some other areas we are considering that are related to package identity are:
- Making package licensing information more obvious to package consumers
- NuGet package signing with digital certificates
- Consistent UI for package ID and package titles in VS and nuget.org so you can quickly uniquely identify a package
Background on NuGet package owners, authors and package IDs
To understand the source of confusion in package source identity, it’s important to review how NuGet works today. From talking to you, we have identified three properties that package consumers rely on to determine the “source” of the NuGet Package:
- Package owner
- Package author
- Package ID prefix
Each of these serve a separate purpose, but having different identifying properties makes it difficult to answer one extremely important question: who produced the package I am about to use in my project?
The package owner is the account on nuget.org that published the package. This value is unique to the nuget.org feed – local feeds or other remote feeds may or may not have any concept of a package owner. This is the value that is displayed when searching for packages on nuget.org:
For the EntityFramework package, the owners are aspnet, EntityFramework, and microsoft.
The package author is defined in the .nuspec file of the .nupkg – it is supposed to represent the person or organization that wrote the code for the package. Let’s look at the EntityFramework package again:
The listed author for the EntityFramework package is “Microsoft”. The data presented to you on nuget.org is different than what you see in Visual Studio, but in this case (as in most cases), the information is consistent. Because one of the owners on nuget.org is microsoft, and the author is also listed as Microsoft, you can be confident this package indeed comes from Microsoft.
Package ID prefix
Another property that package consumers use to identify the source of the package is the package ID prefix. When installing a package on the Package Manager Console, this is the beginning of the package ID – e.g. for the popular ASP.NET MVC package, the package ID prefix is Microsoft.AspNet.MVC. Because it starts with Microsoft, many users trust that this package comes from Microsoft as the owner and author of the package.
Examples of package identity causing potential confusion
Below are just three examples of packages that may be confusing to package consumers. In each of these cases, one of the three properties don’t provide consistent information about the package. For example, the package author may be Microsoft, but the nuget.org account microsoft may not actually be an owner on the package.
Now, I want to stress that these packages are not necessarily bad packages! We are trying to empower NuGet package consumers with information about the package identity. Even though System.Linq.Dynamic has Microsoft as the listed author, but is not owned by microsoft, the package is still a good package – in fact, it has close to 1 million downloads from .NET community members.
Solving the package identity crisis
After talking to many NuGet community members, we have several ideas on how to fix this NuGet package identity problem. Our number one goal is to provide NuGet package consumers with meaningful information about who their package is coming from. In other words, when you are consuming a Microsoft.* package with a Microsoft author, you should quickly be able to determine if it actually comes from Microsoft, or if it comes from a different person or organization.
To do this, we are going to introduce two features: verified package owners and package ID prefix reservation.
Verified package owners
A verified package owner in its simplest form is just an account on nuget.org who has proven to nuget.org administrators that they are who they say they are. They have gone through an application and verification process to prove their identity. In addition, verified owners will be held to a stricter set of terms. Most notably, the author property for their packages must properly identify the source of the package. When you see Microsoft in Visual Studio next to a verified owner indicator, you can be confident that it comes from Microsoft. If you see Microsoft as an author for a package without the visual indicator, then you may want to do some additional research to determine who owns and publishes the package.
Criteria for package owner verification
Verified package owners will not be available to all accounts on nuget.org. Verified package owners must meet certain crtiera:
- There must be significant risk of your packages or identity being confusing to nuget.org package consumers. This is often but not exclusive to the following:
- Impact your packages have on the .NET community
- Popularity of your NuGet packages (number of downloads from nuget.org is just one indicator of popularity)
- Being a co-owner of a package with a verified owner
- This is to drive confidence in the contents of a package that is owned by multiple owners
To start, this will be a limited program that we will expand over time. Verified package owners will get several benefits. The most important one is that top-level packages that are owned by verified owners will have a visual indicator on both nuget.org and in Visual Studio that the package originated from verified owners. We will not evaluate if all transitive dependencies are also verified. If you can trust the author/publisher of the top-level package, you should be able to trust their ability to determine their package dependencies.
Verified package owner mockups
You can see several possible examples of the visual indicator in the mockups below:
Workflow improvement with verified package owners
We’ve learned from our customers about typical package consumption workflows – especially when package identity and trust is important. An example of a typical workflow before verified package owners are available is:
- Discover package in the Visual Studio Package Manager UI or on the internet
- Look at package author in Visual Studio
- Refer to nuget.org to look at package owners and number of downloads (and sometimes source code)
- If the package owners somewhat match the author in Visual Studio, and the package seems generally trusted in the community, then add the package reference
With verified package owners, we hope to reduce the workflow for many of the most critical .NET packages to the following:
- Discover the package in Visual Studio Package Manager UI
- See the verified indicator on a package with an author that you trust, and reference the package
Only if the package is not coming from verified owners that you trust should you have to resort to additional research on nuget.org or elsewhere.
Package ID prefix reservation
While we think package owner verification is a good start at improving identity related confidence for NuGet package consumers, we also want to address some concerns many package authors have expressed to us. There are cases where developers clone an open source repository, create a NuGet package, and publish it to nuget.org with an appropriate package ID. While this is fine in practice, we’ve had several complaints that the package was intentionally not yet on nuget.org by the author of the code. Many times, this is because the code is not yet ready for broad distribution. It could still be pre-release code or not fully supported.
As the code evolves and is ready to be submitted as a NuGet package, the original author of the code cannot publish the package with the package ID they want (since it had previously been published).
With verified package owners being able to reserve package ID prefixes, this problem should be mitigated for key .NET partners. The most influential .NET contributors will be able to reserve a package ID prefix so that future package submissions that match the ID prefix pattern are reserved for them. This allows them to develop their code in the open, and only submit to nuget.org when they are confident the package is ready for broad consumption. If other community members want to publish the package earlier, they are welcome to use a different package ID prefix.
We will not retrofit this to all previously submitted packages (so we don’t destroy existing dependencies), but we will evaluate existing packages and may delist or remove packages that appear to be intentionally abusing a package ID prefix.
Criteria for package ID prefix reservation
Applying for a reserved package ID prefix will require package owners to be verified. Once the package ID prefix application is submitted, the nuget.org team will review the following criteria with the .NET Foundation:
- Does the ID prefix properly identify the package owner?
- Are a significant number of the packages that have already been submitted by the owner under that package ID prefix?
- Is the package ID prefix something common that should not belong to any individual owner or organization?
- Would not reserving the package prefix cause ambiguity and confusion?
What we are striving for is clear messaging on identity of the package and the source of the package. All issued reserved prefixes will be reviewed with .NET Foundation with all criteria heavily considered.
There are a lot of complexities with NuGet package identity and trust. For us to address your needs properly, we desire your input. Please let us know what you think about this in the comments below or by emailing email@example.com. Alternatively, you can post your comments on the NuGet issue tracking this work.
We sincerely thank you for your feedback as we continue to build a better NuGet for everyone!
In the past, NuGet packages were managed in two different ways - packages.config and project.json - each with their own sets of advantages and limitations. With Visual Studio 2017 and .NET Core, we have improved the NuGet package management experience by introducing the PackageReference feature in MSBuild. PackageReference brings new and improved capabilities such as deep MSBuild integration, improved performance for everyday tasks such as install and restore, multi-targeting and more.
Try out PackageReference today!
To get a piece of the PackageReference goodness, download Visual Studio 2017 and create a .NET Standard class library or .NET Core project. These projects come with PackageReference enabled by default. You can also try PackageReference with other project types .
Install your favorite NuGet packages, try out different scenarios and workflows, and if you run into an issue or find something broken, open an issue on GitHub.
PackageReference – the one NuGet format to rule them all
Manage all project dependencies in one place
Just like project to project references or assembly references, you can now view and manage NuGet package references from the MSBuild project file (e.g. csproj).
See only those dependencies you care about
In the past, if your project referenced package A, which in-turn referenced packages B, C and D, you would see all of them listed as your dependencies. With Transitive Package Restore, NuGet dynamically resolves dependencies giving you an uncluttered view of the packages you care about. Additionally, project files are not modified on restore, avoiding merge conflicts and file churn on commits. This also allows the project system to evolve independent of NuGet.
Package installs/updates are now at least 5x faster. With PackageReference and Transitive Package Restore, we no longer stamp every down-level dependency into the project file. In a test project that references 5 packages, with each package having 20-30 dependencies of their own, update/install used to take ~10 mins to complete. With these new features, our tests show that these operations now take ~30ms.
Solution-local packages folders are no longer used – Packages are now resolved against the user’s cache at
%userdata%\.nuget, rather than a solution specific packages folder. This makes PackageReference perform faster and consume less disk space by using a shared folder of packages on your workstation.
Fine control over dependencies and content flow
With the existing features of MSBuild, you can conditionally reference a NuGet package. This allows you to choose package references per target framework, configuration, platform, or other pivots. For example:
<PackageReference Include="NuGet.Versioning" Version="3.6.0" Condition = "'$(TargetFramework)' == 'netstandard10'"/>
You might be using a dependency purely as a development harness and might not want to expose that to projects that will consume your package. In this scenario, you can use the PrivateAssets metadata to control this behavior. For example:
<PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0">
You can control the flow of dependency assets using Include/Exclude Assets metadata.
In the following example, everything except the content files from the package would be consumed by the project and everything except content files and analyzers would flow to the parent project.
<PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0">
You now have flexibilty to express dependency versions using either version ranges or floating versions. In the first example, using version range, you can restrict the package version range which NuGet accepts from 1.3.2 up to 1.4.x, but not 1.5 and higher. In the second example, using floating version, NuGet will always bring the latest version of the ExamplePackage that matches the pattern 1.4.x.
<PackageReference Include="ExamplePackage" version="[1.3.2,1.5)" />
<PackageReference Include ="ExamplePackage" version="1.4.*"/>
You can now author NuGet packages by specifying NuGet properties in your project file. You can also define these properties from the project properties. Additionally, you can choose to auto-generate a NuGet package on every build by checking the “Generate NuGet package on build” property.
Build packages directly from a project
Pack and Restore are msbuild targets, making NuGet a first class MSBuild citizen. For example, you can execute
msbuild /t:pack in a project directory to generate a NuGet package using the properties and metadata declared in the project file.
In a CI/CD scenario, NuGet error and warnings are collated with the MSBuild output, giving you a single view of your build output.
Background Package Restore
In prior configurations, you had to perform a build or an explicit restore to restore NuGet packages. With NuGet 4.0, background package restore automatically downloads and adds or removes NuGet packages as you edit PackageReference and save your project files.
Package project duality
As a package author, you can now expect the exact same behavior when referencing a library either as a Project to Project reference or as NuGet package. This streamlines your inner loop when authoring NuGet packages as you no longer need to go through the change-build-pack-restore loop to test a change.
Develop against multiple TFMs
You can now specify multiple target frameworks (TFMs) and at pack time, NuGet will do the right thing to create a nupkg with the correct package structure. For example:
What about other project types that are not .NET Core?
You can get a first look of what will come in the next NuGet update. Hop on to the Visual Studio 2017 Update 1 Preview 2 bandwagon. Once you have the VS 2017 U1 Preview 2, you can try PackageReference with any packages.config based project. Navigate to
Tools > Options> NuGet Package Manager > General and check the “Allow format selection on first package install” option.
Create a new packages.config based project and attempt to install a NuGet package. You will be prompted by the dialog below. Select the PackageReference option and click ok.
Some of the features discussed earlier are not yet fully supported for packages.config based projects such as defining nuspec metadata in project files, building packages directly from a project, background package restore, developing against multiple TFMs, and package project duality. We are hard at work to bring full PackageReference support to these project types. Our goal is to eventually make PackageReference the default and move away from all other formats.
Will existing NuGet package management formats continue to work?
The PackageReference feature is only supported in Visual Studio 2017. We remain fully committed to maintaining compatibility of existing projects created with Visual Studio 2015 in Visual Studio 2017. Your packages.config and project.json managed projects will continue to work in both versions of Visual Studio.
Will existing NuGet packages work if I am using PackageReference for WPF, Windows Forms or ASP.NET projects?
While we have done a lot of work to ensure that existing packages on NuGet.org just work with the PackageReference format, there are a few scenarios that will not be supported in the PackageReference world and might impact your ability to migrate away from packages.config. Some examples of scenarios that will not be supported include content folders (we have introduced ContentFiles), XDT transforms, PowerShell scripts i.e. install.ps1 and uninstall.ps1 (only init.ps1 is supported) . If you come across a package you consume in your WPF or Windows Forms app that worked previously but does not work on migrating your project to PackageReference, we would love to hear from you, so that we can investigate what the incompatibilities might be.
We want to hear your feedback!
We want NuGet to meet the evolving needs of our community. If you would like to share your pain points, and your current or future needs, hit us up at feedback@NuGet.org. You can also leave a comment below, and as always, if you run into any issues or have an idea, open an issue on GitHub.
Visual Studio 2017 comes with NuGet 4.0 which adds support for .NET Core, has a bunch of quality fixes and improves performance. This release also brings several improvements like support for PackageReference, NuGet commands as MSBuild targets, background package restores, and more.
Visual Studio 2017 RTM is available for download here. The NuGet Package Manager extension is already built-in, so you do not have to install or update it.
NuGet.exe 4.0 is also available for download as a separate component, here.
NuGet Package Manager Extension in Visual Studio 2017
Starting with NuGet 4.0 in Visual Studio 2017, the NuGet Package Manager will be shipped as a part of Visual Studio, and newer versions will not be available for download from the VS extensions gallery. NuGet updates will be pulled in automatically along with other Visual Studio updates.
The NuGet 4.0 Package Manager Extension is currently not available for Visual Studio 2015 (Visual Studio 2015 comes with NuGet 3.4.4, and NuGet 3.5.0 is available as an explicit download for Visual Studio 2015 as well). NuGet 4.0 builds upon several new features and bug fixes available only in Visual Studio 2017, and hence the newer NuGet experiences will not be available in Visual Studio 2015. At the same time, we want packages to work seamlessly across Visual Studio versions. We will be monitoring feedback to determine what experiences we want to enable in Visual Studio 2015 in a future release (for example, the introduction of newer TFMs).
PackageReference will become the standard way to manage NuGet dependencies across all project types. With NuGet 4.0, PackageReference is fully supported for .NET Core projects. This allows you to use MSBuild conditions to choose package references per target framework, configuration, platform, or other pivots. It also allows for fine-grained control over dependencies and content flow. Here is an example of how you would add a PackageReference in your MSBuild-based project file:
<PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0"/>
You can also try PackageReference with other project types such as WinForms, Windows Presentation Foundation(WPF), and Universal Windows Platform (UWP). More details about usage and known limitations of using PackageReference in non-.NET Core projects will be available on this blog soon.
First class MSBuild citizen
In the past, it was a little tricky to make NuGet work with MSBuild. In this release, we are shipping Restore and Pack as first class MSBuild targets. This will allow you to easily work with NuGet as you would with any task or target in MSBuild.
You can now produce packages directly from a project. For example, you can do
msbuild /t:pack in a project directory which would generate a NuGet package using the properties and metadata declared in the csproj file of the project.
In CI systems, you no longer need to download
nuget.exe and run
nuget restore to restore packages. You can now use
msbuild /t:restore to restore packages.
Background Package Restore
In the past, you had to perform a build or an explicit restore to restore NuGet packages. With NuGet 4.0, background package restore automatically downloads and adds or removes NuGet packages as you edit PackageReference and save your project files.
New commands in the .NET CLI
We have added new commands for the .NET CLI -
dotnet nuget locals,
dotnet nuget push, and
dotnet nuget delete.
dotnet nuget locals allows you to manipulate and work with the nuget caches on your machine.
dotnet nuget push / delete – enables pushing packages to or deleting packages from NuGet servers. Additionally,
dotnet restore and
dotnet pack now have the same behavior as MSBuild restore and MSBuild pack providing a consistent and reliable experience.
dotnet restore == msbuild /t:restore
dotnet pack == msbuild /t:pack
The following are some performance improvements that you might notice with NuGet 4.0:
nuget update for UWP, WPF and other project.json based projects is now much faster. In our sample solution with 20 UWP projects, updating packages is 6 times faster than before. For
packages.config based projects,
nuget update is now about 20% faster.
nuget restore for UWP, WPF and other project.json based projects has been improved. In one of our sample projects, restore times have been reduced from about 3800ms to about 400ms.
nuget update/install for packages that have deep dependencies is now faster by an order of magnitude. For a sample scenario with 5 targets each having 20-30 deep dependency chains,
nuget update/install used to take about 10 mins to complete, compared to about 30ms now.
In .NET Core, tool restores have been optimized so that tool references are restored only once per solution instead of once for every project.
Default Location for the machine-wide NuGet.config
In Visual Studio 2017 and above, the machine-wide NuGet.config is located at
%ProgramFiles(x86)%\NuGet\Config\. Going forward, nuget.exe v4.0.0+ will also treat this as the new location for the machine-wide configuration. The primary driver for the change is to improve security in a multi-user scenario. Previously we would write to the
%ProgramData% folders which don’t require Admin privileges to modify.
%ProgramFiles(x86)% folders are protected and only users with Administrative privileges, or those granted permissions by an administrator can change their contents.
%ProgramData%\NuGet\Config\ will no longer be implicitly referenced or considered for hierarchical merging of
NuGet.config. This is only applicable if you were previously using machine-wide NuGet configuration files.
Solution - You must manually migrate existing config files from
4.0 release notes
We want to hear your feedback!
We want NuGet to meet the evolving needs of our community. If you would like to share your pain points, and your current or future needs, hit us up at firstname.lastname@example.org. You can also leave a comment below, and as always, if you run into any issues or have an idea, open an issue on GitHub.