Hide Transitive NuGet Dependencies with PrivateAssets
Learn how to hide a transitive NuGet package from consumers using the PrivateAssets attribute in PackageReference.
04 Sept 2025, 12:50 UTC

Problem: Leaking Transitive Dependencies
When a library uses a third‑party package only for internal work, that package can appear in consumers’ dependency graphs, causing version conflicts or exposing unwanted APIs.
Solution: PrivateAssets Attribute
In SDK‑style projects that use PackageReference, the PrivateAssets metadata tells NuGet which assets of a referenced package should be hidden from downstream consumers. Setting it to all hides runtime, compile and build assets.
Worked Example: Hiding Newtonsoft.Json
- Create the library
dotnet new classlib -n MyLib
cd MyLib
- Add the dependency with PrivateAssets
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" PrivateAssets="all" />
</ItemGroup>
Save the file; the library can still use using Newtonsoft.Json; in its code.
- Create a consumer app
dotnet new console -n ConsumerApp
cd ConsumerApp
- Reference the library
dotnet add reference ../MyLib/MyLib.csproj
- Restore and verify
dotnet restore
Check that the hidden package does not appear:
dotnet list package --include-transitive
You should see MyLib and any other transitive packages, but Newtonsoft.Json absent. You can also open ConsumerApp/obj/project.assets.json and confirm the package is missing from the libraries section.
Trade‑Offs and Limitations
- Consumers can still add the hidden package explicitly if they need it.
- Some older tooling or custom build scripts that ignore the SDK style may not honor PrivateAssets.
- Only works with PackageReference; projects using packages.config cannot use it.
Actionable Take‑Away
- Use
PrivateAssets="all"for any third‑party package that is purely an internal implementation detail. - Place the attribute directly on the PackageReference line in your .csproj.
- After adding it, run
dotnet restoreanddotnet list package --include-transitiveto confirm the package is hidden. - Document the reason in a README or code comment so future maintainers understand the intent.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.