1. Background
March 19, 2026 ยท View on GitHub
- 1. Background
- 2. Decisions
- 3. Conclusions
1. Background
This document answers the question: "How are MSIX and Dynamic Dependencies defined and implemented to meet versioning requirements for Windows App SDK 0.8 through 1.x?"
This document defines how Windows App SDK packages are named and versioned.
1.1. Scope
This decision focuses on install- and run-time beyond 0.5 and, in particular, MSIX and Dynamic Dependencies in 0.8 and 1.x.
Development- and build-time issues are out-of-scope for this decision. Windows App SDK's requirements for dev- and build-time and how NuGet, VISX and other tech are handled do not impact this decision.
As this spec is focused on install- and run-time it results in a stance on binary compatibility. Source compatibility is only significant at development- and build-time so a decision on source compatibility is out-of-scope for this decision.
1.2. Terminology
1.2.1. Project Reunion vs Windows App SDK
This document defines the MSIX versioning details for version 0.8 thru 1.x.
The project went thru a name change from "Project Reunion" in 0.8 to "Windows App SDK" in 1.0. Artifact names are kept historically accurate. Textual prose has been updated to use the new "Windows App SDK" name for consistency, even when referring to earlier versions.
Similarly, examples may cite ProjectReunion but the same logic applies to 1.x despite name changes.
1.2.2. Version Number = MSIX
SemVer defines a version number as MAJOR.MINOR.PATCH[-prerelease][+build].
MSIX defines a version number as Major.Minor.Build.Revision.
To avoid ambiguity this document uses MSIX's definition and terms unless stated otherwise.
1.2.3. Windows App SDK's MSIX Packages
Windows App SDK 0.5 has 1 MSIX package: Microsoft.ProjectReunion.0.5 aka WARfwk (formerly PRfwk).
This contains the vast majority of Windows App SDK.
Windows App SDK 0.8 has 3 MSIX packages
Microsoft.WindowsAppRuntimeaka WARfwkMicrosoft.WindowsAppRuntime.Mainaka WARmainMicrosoft.WindowsAppRuntime.DDLMaka WARddlm
WARmain and WARddlm supplement WARfwk to do things a Framework packge can't (e.g. Packaged COM). See the Dynamic Dependencies spec and Windows App SDK: MSIX Packages for more details.
Windows App SDK 1.0 has 4 MSIX packages
Microsoft.WindowsAppRuntimeaka WARfwkMicrosoftCorporationII.WinAppRuntime.Mainaka WARmainMicrosoftCorporationII.WinAppRuntime.Singletonaka WARsingletonMicrosoft.WinAppRuntime.DDLMaka WARddlm
WARsingleton supplements WARmain to provide a mechanism for features needing singular global behavior across all versions of Windows App SDK. See Windows App SDK: MSIX Packages for more details.
1.2.4. Binary Compatibility
"Binary Compatibility": Existing, compiled code can rely on new version of compiled library code without change, and expect to run without issue. Binary compatibility relies on a strong contract between the library and caller including both the shape and behavior of the API.
If an application relies on unspecified behavior, intentionally or otherwise, binary compatibility can be hard to maintain. Nonetheless, Windows has demonstrated that it is possible, with effort, to maintain a high degree of binary compatibility over an extended period of time.
1.2.5. Source Compatibility
"Source Compatibility": The version of the library can be changed, and the code will build without issue.
In practice, perfect source compatibility is unachievable in most programming languages. E.g. "using" statements can lead to name collisions when a library introduces new types. In contrast, a project that does not commit to source compatibility may require significant code changes when building with later versions, due to changes in the public surface area of the API.
1.3. Impacted Components
Dynamic Dependencies, ProjectReunionInstaller.exe and the build pipeline are not currently in sync. Work is required (regardless the decision) to align on a common solution.
Demos, samples, documentation, functional testing and E2E integrated testing are impacted.
1.4. MSIX and SemVer
MSIX's versioning model overlaps with SemVer but isn't fully compatible. See here for more details.
1.5. Dynamic Dependencies
Windows App SDK's DynamicDependencies (DynDep) relies on an elegant dance with Windows' inbox behavior to provide the expected outcome (without servicing Windows). This requires a deep understanding of MSIX's behavior and Windows App SDK's versioning model to correctly identify and select the appropriate Windows App SDK framework package (aka WARfwk) at runtime. More details are available here.
Dynamic Dependencies support is being added to Windows, aka OS DynDep. Care has been taken to keep WinAppSDK+OS behavior aligned to facilitate eventual use and migration from Windows App SDK's implementation to Windows'. OS DynDep provides a richer, more efficient and reliable solution with less developer friction than WinAppSDK DynDep. We will eventually polyfill WinAppSDK DynDep's implementation to use OS DynDep when available and (someday) rely entirely on OS DynDep when downlevel support is no longer relevant.
1.6. Windows App SDK Versioning Requirements
Windows App SDK's versioning model has been discussed in detail but not documented in one place. This spec pulls together that disparate information into a unified whole.
The versioning meta-requirements are briefly summarized here:
- Require no Windows servicing
- Support Semantic Versioning (SemVer)
- Support a clear division of incompatibility (Breaking Change) across major/disruptive releases
- Support servicing across minor/less-disruptive releases
- Support critical servicing e.g. MSRC security fixes
- Support packaged and unpackaged apps
- Support multiple tags of 'release' (Stable, Preview, ...) aka Channels
- Be implementable across our key technologies including Dynamic Dependencies, NuGet, MSIX, MS Store and VSIX
- Support WinAppSDK DynDep leveraging OS DynDep (in future Windows versions) via polyfill (initially where available, eventually 100%)
These requirements need careful balance and multiple mechanisms to meet them all. This spec focuses on install- and run-time needs, specifically MSIX and Dynamic Dependencies (DynDep) for unpackaged apps.
The versioning solution used in 0.5 is insufficient for Windows App SDK's support for unpackaged apps (e.g. MSIX naming patterns don't work for the DynamicDependency Lifetime Manager (DDLM) package). See section 2. Decisions for more details. Past decisions are incorporated to the extent possible but additions and changes are needed.
Packaged apps bring a subset of requirements vs unpackaged apps so this decision is expected to work equally well for packaged apps.
MS Store brings similar needs and constraints as MSIX so this decision is expected to work equally well for MS Store distribution.
2. Decisions
Current versioning design and practice has some areas of ambiguity or gaps for new scenarios (e.g. unpackaged apps). These issues are noted with solutions and the recommended path forward.
Jump ahead to 3. Conclusions to skip the alternatives considered, detailed explanations and why the recommended solutions are chosen.
2.1. Decision 1: Breaking Change Boundary for Version 2.*+
Per SemVer section 4
Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable.
There's no mention if this requires or assumes any technical enforcement.
This does not guarantee incompatibility across version 0.y.z but it doesn't guarantee compatibility either. Windows App SDK defines specific rules for Windows App SDK to address this ambiguity.
Option A: MSIX package Name includes Major.Minor.Build if Major=0. Servicing can be done
via changes to .Revision e.g. Microsoft.ProjectReunion.0.8.0 for version 0.8.0.0.
Servicing (bugfix) increment the .Build value e.g. 0.8.1.0, 0.8.2.0, etc with package Name
Microsoft.ProjectReunion.0.8.1 etc. Applications are required to rebuild to use the update at
runtime.
MSRC updates would be 0.8.0.1, 0.8.0.2, 0.8.1.1, etc. Applications always use MSRC updates on a
system matching their Major.Minor.Build.
Option B: MSIX package Name includes Major.Minor if Major=0. Servicing can be done via
changes to .Build and .Revision e.g. Project Microsoft.ProjectReunion.0.8 for version 0.8.0.0.
Servicing (bugfix) increment the .Build value e.g. 0.8.1.0, 0.8.2.0, etc with package Name
Microsoft.ProjectReunion.0.8.1 etc. Applications use the latest update on a system
matching their Major.Minor. No rebuild is necessary. Applications cannot block running with
servicing updates.
MSRC updates would be 0.8.0.1, 0.8.0.2, 0.8.1.1, etc. Applications always use MSRC updates on a
system matching their Major.Minor.
Option C: Never make MSIX Framework packages with version Major=0.
Deployment does not support SemVer section 4. Deployment doesn't treat version 0 different than any
other version. If Deployment finds multiple applicable packages satisfying a dependency it chooses
the highest version (per VersionSupercedence1).
1 VersionSupercedence can be defeated in very narrow cases e.g. Packages installed with DeploymentOptions.ForceUpdateFromAnyVersion are always used, even if a lower version than other applicable packages. Other exotic cases exist but the overwhelming norm without exception is 'highest version wins'.
Recommendation:
Decision 1: Breaking Change for version 2.x+
Option A is selected. This provides better stability for developers. Given the same Major version the newer version is backwards compatible with previous releases in the same Major version.
2.1.1. Current practices in Microsoft-authored Framework packges.
There is no consistency of version in package Name amongst existing Framework packages. Per
powershell -c "$(get-appxpackage -packagetypefilter framework).packagefamilyname|sort" one can see
some of the more common frameworks:
- None: Microsoft.Advertising.JavaScript, Microsoft.Advertising.Xaml, Microsoft.DirectXRuntime, Microsoft.Media.PlayReadyClient, Microsoft.Services.Store.Engagement
- Minor: Microsoft.NET.CoreRuntime, Microsoft.NET.Native.Framework, Microsoft.NET.Native.Runtime, Microsoft.UI.Xaml, Microsoft.VCLibs, Microsoft.WinJS
VCLibs sometimes goes further with additional qualifiers in their Name including: .debug, .Universal, .UWPDesktop.
No version in Name implies the framework has yet to produce a breaking change, i.e. in SemVer-speak these frameworks are still MAJOR=X and yet to produce MAJOR=X+1.
2.2. Decision 2: Release Tags (Stable, Preview, ...)
How do we distinguish release across channels, e.g. a 'Stable' package from a 'Preview' package?
- Windows App SDK adds a "-preview##" tag to the package Name. The ## is a 1 or 2 digit base-36 number[0-9a-z] to distinguish one release within the channel from another one.
Shorter Tags as needed "-preview##" adds 10 characters to package Name. "-experimental##" adds 14 characters. Package Name is restricted to 50 characters maximum.
Option A: -preview##
Option B: -pre##
Option C: -p##
Recommendation: Option A and C (for packages where this could ever be necessary).
All tags have a long name (Option A) and a short (1-2 characters) name (Option C).
Option C is used when Option A doesn't work due to package Name length restrictions. Currently WARddlm and Singleton use Option C.
2.3. Decision 3: Version Encoding
What data's encoded in the MSIX Version, and how?
The following notation is used to describe the possible options
- X = Major version
- N = Minor version
- P = Patch (per SemVer definition i.e. the 3rd field in a version)
- Y = Year
- M = Month
- D = Day
- E = Elapsed days since an epoch e.g. if Epoch=2021/01/01 then 2021/6/4=154
- B = Build number (reset to zero when Major or Minor changes)
- 0 = Zero
Single character indicates variable-length without leading zeros. Multiple characters indicates fixed-length with leading zeroes if necessary. For example, Y=1 vs YY=01.
NOTE: MSIX version's 4th field (Revision) is reserved for security updates.
Examples are provided for the following theoretical versions...
- Windows App SDK 0.8.1, date=2021/6/4, build=123, elapsed=154
- Windows App SDK 1.2.3, date=2021/12/31, build=123, elapsed=364
- Windows App SDK 17.14.3, date=2031/10/20, build=123, elapsed=3944
| Option | Syntax | Example | Information | Comments |
|---|---|---|---|---|
| A | X.N.P.0 | 0.8.1.0 1.2.3.0 17.14.3.0 | Major Minor Patch | |
| B | X.NYYMM.DDPPP.0 | 0.82106.04001.0 1.22112.31003 --error-- | Major Minor Patch Date | Minor max is 6 Patch max is 999 WinUI 2.x used this encoding Windows App SDK 0.5 used this encoding |
| C | XNN.PYYMM.DDBBB.0 | 8.12106.04123.0 102.32112.31123.0 1714.33110.20123.0 | Major Minor Patch Date Build | Minor max is 99 Patch max is 6 Build max is 999 |
| D | NPPP.E.B.0 | 8001.154.123 2003.364.123 17014.3944.123.0 | Minor Patch Elapsed Build | Minor max is 64 Patch max is 999 Build max is 65535 |
| E | NPP.E.B.0 | 801.154.123 203.364.123 1714.3944.123.0 | Minor Patch Elapsed Build | Minor max is 99 Patch max is 99 Build max is 65535 |
Recommendation: For 2.x+, Option A is selected.
Option A works. This is the simplest option to release and understand.
NOTE: A Major.Minor is constrained to 999 Patches (to avoid exceeding DDLM limits). See 2.5. Decision 5: Package Names for more details.
Option B worked for WinUI 2.x and Windows App SDK 0.5 but is too limiting given it can't support Minor versions beyond 6. It's also a complicated encoding scheme with date injected between Minor and Patch (not readily legible).
Option C is too limiting given it can't support Patch versions beyond 6.
Option D relies on the package Name including Major version. This leaves sufficient space in the version to encode up to 99 Minor and 99 Patch versions. Date encoding as an Epoch reduces the size while supporting 20+ years with only 4 digits.
Option E is a variant of Option D except Patch version is restricted to 2 digits, but it's an unnecessary simplification.
2.3.1. Windows App SDK 0.5 Notation
Windows App SDK 0.5 encodes MSIX versions as M.NYYMM.DDPPP.0
- M = Major version
- N = Minor version
- YY = Year
- MM = Month
- DD = Day
- PPP = Patch
All fields are fixed-size with leading zeroes as needed. For example, Windows App SDK 0.5.0's MSIX package has a version of 0.52103.25000.0
- Major = 0
- Minor = 5
- Year = 21 (aka 2021)
- Month = 03
- Day = 25
- Patch = 000 (if we have a 0.5.1 release this would be
001)
This doesn't scale going forward e.g. MSIX version is a DotQuadNumber aka uint16[4]. If 0.8 was
released on May'31, 2021 MSIX version would be 0.82105.31000.0
2.3.2. WinUI 2.x Notation
WinUI 2.x encodes MSIX versions as M.NYYMM.DDPPP.0 (same as Windows App SDK 0.5). This runs into
issues starting with WinUI 2.7, as identified by WinUI version schema sometime can't applied to
MinVersion
#4008.
2.4. Decision 4: Package Names
Windows App SDK 2.0+ has 4 MSIX packages.
- WARfwk:
Microsoft.WindowsAppRuntime.<major>[-tag##] - WARmain:
MicrosoftCorporationII.WinAppRuntime.Main.<major>[-tag##] - WARsingleton:
MicrosoftCorporationII.WinAppRuntime.Singleton[-shorttag##] - WARddlm:
Microsoft.WinAppRuntime.DDLM.<major>.<minor>.<patch>.<revision>-<shortarchitecture>[-shorttag##]
where
- major = Major version number of the release, base-10, no leading zeros
- minor = Minor version number of the release, base-10, no leading zeros
- patch = Patch version number of the release, base-10, no leading zeros
- revision = Revision version number, base-10, no leading zeros
- shortarchitecture = Allowed values: "x8", "x6", "a6"
- tag = Allowed values: "", "preview", "experimental"
- shorttag = Allowed values: "", "p", "e"
- "##" = the current build number for that release type. It is a 1 or 2 digit base-36 number[0-9a-z].
NOTE: Starting 2.0, the major, minor, and patch versions will now be the same as the project release versions. The exception to that is Singleton, since there is one package covering all releases. That package can't "go back" to Major=2, so we will add a 8000 to the Major for that package.
For Information on how WindowsAppSDK Projects determines these versions, see the WindowsAppSDKVersioning spec
Version's fields have values 0-65535.
WARddlm requires architecture in its package Name to support concurrent use of different architectures of a framework. See the Dynamic Dependencies spec for more details.
This leads to package Name length issues even for common cases:
| Package | Average | AverageLength |
|---|---|---|
| WARfwk | Microsoft.WindowsAppRuntime.2-experimental10 | 44 |
| WARmain | Microsoft.WindowsAppRuntime.Main.2-experimental10 | 46 |
| WARsingleton | Microsoft.WindowsAppRuntime.Singleton-experimental10 | 52 |
| WARddlm | Microsoft.WinAppRuntime.DDLM.1.15.12345.24680-arm64-preview10 | 61 |
| Package | Min | MinLength |
|---|---|---|
| WARfwk | Microsoft.WindowsAppRuntime.2-preview0 | 38 |
| WARmain | Microsoft.WindowsAppRuntime.Main.1-preview0 | 43 |
| WARsingleton | Microsoft.WindowsAppRuntime.Singleton-preview0 | 46 |
| WARddlm | Microsoft.WinAppRuntime.DDLM.1.0.0.0-arm64-preview0 | 51 |
| Package | Max | MaxLength |
|---|---|---|
| WARfwk | Microsoft.WindowsAppRuntime.65535-experimental10 | 48 |
| WARmain | Microsoft.WindowsAppRuntime.Main.65535-experimental10 | 53 |
| WARsingleton | Microsoft.WindowsAppRuntime.Singleton-experimental10 | 52 |
| WARddlm | Microsoft.WinAppRuntime.DDLM.65535.65535.65535.65535-arm64-preview10 | 68 |
Possible options we can use to shorten package Name:
- Change the Name constant/prefix to a shorter string e.g. change "Microsoft.WindowsAppRuntime.Main" to "Microsoft.WinAppRuntime.Main", etc
- Dictate max values e.g. Major=0-99
- Encode values as base-16
- Replace -channel with a shorter string e.g. replace "-preview" with "-pre", "-p", "p"
- Encode the channel name in the delimiter between name+version e.g. Microsoft.WinAppRuntime.DDLM.preview01.1.0.0.0-arm64
- Encode tag in the delimiter between version+architecture e.g. Microsoft.WinAppRuntime.DDLM.1.0.0.0p1arm64 using P01 for Preview1, E01=Experimental1, ...
- Name WARddlm differently from WARfwk and WARmain e.g. use "-p01" for WARddlm regardless if WARfwk and WARmain use "-preview01"
WARddlm is needed until Dynamic Dependencies is 100% based on OS DynDep.
Best case (!) WARddlm exists until the minimum supported Windows release is Cobalt.
Recommendation: The general package naming syntax is
Microsoft.ProjectReunion[.SubName]-<major>[-tag##]. WARddlm and WARsingleton are
exceptions to the rule (see below).
Windows App SDK 2.0 will use package Names of...
- WARfwk:
Microsoft.WindowsAppRuntime.<major>[-tag##] - WARmain:
Microsoft.WindowsAppRuntime.Main.<major>[-tag##] - WARsingleton:
Microsoft.WindowsAppRuntime.Singleton[-shorttag##] - WARddlm:
Microsoft.WinAppRuntime.DDLM.<major>.<minor>.<patch>.<revision>-<shortarchitecture>[-shorttag##]
Using Decision 4: Version Encoding = Option D (M.N.P.0) WARddlm's maximum package Name length is
Microsoft.WinAppRuntime.DDLM.12345.12345.12345.12345-arm64-p01 = 62 characters. This can be reduced
with the following rules:
- Major version <= 999
- Minor version <= 999
- Patch number <= 999
- Revision (security update) <= 99
- Architecture = 2 characters (x8=x86, x6=x64, a6=arm64)
In the unlikely event that Minor or Patch reach these limits, then the Major (for the Minor) or Minor (for the Patch) will bump for all packages in order to keep these restrictions. If\When we reach Major version 1000, then the Major version will be the Actual Major %1000. This works, since the Major is also included in the name.
This produces a worst case for WARddlm in Windows App SDK 99.888.777.66 ARM64 Preview 3 to the following identifiers:
- Package Name =
Microsoft.WinAppRuntime.DDLM.999.888.777.66-a6-p03= 50 characters - PackageFullName =
"Microsoft.WinAppRuntime.DDLM.999.888.777.66-a6-p03_999.888.7777.66_arm64__8wekyb3d8bbwe" - PackageFamilyName =
"Microsoft.WinAppRuntime.DDLM.999.888.777.66-a6-p03_8wekyb3d8bbwe" - PACKAGE_VERSION struct =
999.888.777.66 - PACKAGE_VERSION uint64 =
0x03E7037803090042
3. Conclusions
Decision 1: Windows App SDK version 2.*+ encodes Major into MSIX package Names.
Decision 2: Windows App SDK supports an optional 'tag' to indicate a non-Stable channel.
A 'tag' comes in long and short (2-3 character) forms e.g. -preview## and -p##.
The following are valid 'tag's: *-experimental##, -e## *-preview##, -p##
Decision 3: Windows App SDK encodes version as <major>.<minor>.<patch>.<revision>
i.e. format encoding M.N.P.0. See
2.4. Decision 3: Version Encoding for more details.
Decision 4: MSIX package Names use the format
Microsoft.WindowsAppRuntime[.SubName]-<major>[-tag]. WARddlm is an exception due to Name
length constraints. The specific packages Names in Windows App SDK 2.0:
- WARfwk:
Microsoft.WindowsAppRuntime.<major>[-tag] - WARmain:
MicrosoftCorporationII.WinAppRuntime.Main.<major>[-shorttag] - WARsingleton:
MicrosoftCorporationII.WinAppRuntime.Singleton[-shorttag] - WARddlm:
Microsoft.WinAppRuntime.DDLM.<major>.<minor>.<patch>.<revision>-<shortarchitecture>[-shorttag]
See 2.4. Decision 4: Package Names for more details.