FrameworkCompatibleVersions 1.0.0
<Sdk Name="FrameworkCompatibleVersions" Version="1.0.0" />
#:sdk FrameworkCompatibleVersions@1.0.0
FrameworkCompatibleVersions
An MSBuild Project SDK that lets a consumer mark selected NuGet dependencies as framework-compatible versions without repeating target-framework conditions for every package.
The SDK is deliberately package-agnostic. It contains no list of package IDs and never adds dependencies. Consumers choose the packages by adding FrameworkCompatibleVersion="true" to their own PackageVersion or PackageReference items.
Installation and usage
Recommended: centralize with global.json + Directory.Build.props/Directory.Build.targets
For any repository with more than a single project, the recommended approach is to pin the SDK version once in global.json and import the SDK once from the root MSBuild files. This keeps individual project files clean and avoids repeating the SDK reference (and version) in every <Project Sdk="..."> line.
- Pin the SDK version in
global.json:
{
"msbuild-sdks": {
"FrameworkCompatibleVersions": "1.0.0"
}
}
- Import the SDK's
.propsnear the top ofDirectory.Build.props:
<Project>
<Import Project="Sdk.props" Sdk="FrameworkCompatibleVersions" />
</Project>
- Import the SDK's
.targetsnear the bottom ofDirectory.Build.targets:
<Project>
<Import Project="Sdk.targets" Sdk="FrameworkCompatibleVersions" />
</Project>
With this in place, every project under that directory automatically participates. The individual project files remain plain:
<Project Sdk="Microsoft.NET.Sdk">
Because the SDK is package-agnostic, nothing is applied until a project (or a shared Directory.Packages.props/Directory.Build.props) opts specific packages in with FrameworkCompatibleVersion="true". Projects that should not participate can set <FrameworkCompatibleVersionsEnabled>false</FrameworkCompatibleVersionsEnabled>.
Alternative: per-project SDK reference
A single project (or a repository that prefers not to use root MSBuild files) can reference the SDK directly alongside the normal .NET SDK, pinning the version inline:
<Project Sdk="Microsoft.NET.Sdk;FrameworkCompatibleVersions/1.0.0">
Or, with the version centralized in global.json as shown above, the version can be omitted:
<Project Sdk="Microsoft.NET.Sdk;FrameworkCompatibleVersions">
Central Package Management
With Central Package Management, opt packages in where their versions are declared:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.Extensions.Http" FrameworkCompatibleVersion="true" />
<PackageVersion Include="System.Text.Json" FrameworkCompatibleVersion="MatchingMajor" />
<PackageVersion Include="Pinned.Package" Version="1.2.3" />
</ItemGroup>
</Project>
The consuming projects continue to use ordinary versionless package references:
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Http" />
<PackageReference Include="System.Text.Json" />
<PackageReference Include="Pinned.Package" />
</ItemGroup>
When Central Package Management is enabled, FrameworkCompatibleVersions automatically enables CentralPackageFloatingVersionsEnabled because the selected versions are floating.
Direct PackageReference usage
Without Central Package Management, apply the metadata directly to the package reference:
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Http" FrameworkCompatibleVersion="true" />
<PackageReference Include="System.Text.Json" FrameworkCompatibleVersion="true" />
<PackageReference Include="Pinned.Package" Version="1.2.3" />
</ItemGroup>
Unmarked package items are left unchanged.
Version policy
FrameworkCompatibleVersions supports two policies, selected per package through the value of the FrameworkCompatibleVersion metadata:
| Metadata value | Policy |
|---|---|
true |
Highest tested against (the default). |
HighestTestedAgainst |
Identical to true. |
MatchingMajor |
A package major that matches the target framework's own runtime major. |
Highest tested against (true / HighestTestedAgainst)
| Target framework | NuGet version expression |
|---|---|
| Earlier than .NET 6 | [6.*,7.0.0) |
| .NET 6 and .NET 7 | [8.*,9.0.0) |
| .NET 8 and .NET 9 | [10.*,11.0.0) |
| .NET 10 and later | [*,13.0.0) |
Matching major (MatchingMajor)
Each target framework resolves to a package major that matches its own runtime major:
| Target framework | NuGet version expression |
|---|---|
| .NET 5 | [5.*,6.0.0) |
| .NET 6 | [6.*,7.0.0) |
| .NET 7 | [7.*,8.0.0) |
| .NET 8 | [8.*,9.0.0) |
| .NET 9 | [9.*,10.0.0) |
| .NET 10 | [10.*,11.0.0) |
| .NET 11, 12, 13 | [11.*,12.0.0), [12.*,13.0.0), [13.*,14.0.0) |
| .NET Core App 3.x | [3.*,4.0.0) |
Target frameworks earlier than .NET 5 are trickier: netstandard, .NET Framework, and legacy TargetFrameworkVersion-only projects have no runtime major, and package majors before the .NET 5 unification are not aligned across ecosystems (for example, the Microsoft.Extensions.* packages have no 4.x). For those, MatchingMajor falls back to the lowest broadly-available major that still supports netstandard2.0 ([2.*,3.0.0)), while .NET Core apps resolve to their own major (netcoreapp2.x → [2.*,3.0.0), netcoreapp3.x → [3.*,4.0.0)).
NuGet resolves each floating expression to one concrete stable package version during restore.
Multi-targeting
The SDK evaluates the policy separately for each inner build. A project targeting, for example:
<TargetFrameworks>netstandard2.0;net8.0;net10.0</TargetFrameworks>
can declare a package once with FrameworkCompatibleVersion="true"; each target framework receives its corresponding version expression.
Directory.Build.props and Directory.Packages.props
The metadata can live wherever the consumer normally declares the item, including the project file, Directory.Build.props, Directory.Packages.props, nested variants of those files, or explicitly imported .props files. FrameworkCompatibleVersions works against the evaluated PackageVersion and PackageReference items rather than maintaining its own package list.
Legacy .NET Framework projects
Legacy non-SDK-style .NET Framework projects can use FrameworkCompatibleVersions when they use PackageReference, a sufficiently modern MSBuild/NuGet toolchain, and an MSBuild SDK reference. Projects that expose TargetFrameworkVersion receive the pre-.NET-6 policy.
packages.config is intentionally not supported.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 58 | 9/21/2026 |
Initial release.