ARM64_Lab

Windows on ARM64 AppX architecture census: 145 Arm64 packages out of 240

In this article
  1. Getting the data into JSON
  2. The architecture inventory
  3. What remained as X64 and X86
  4. Where it failed
  5. Why counting matters

Among the 240 MSIX / Appx packages visible through Get-AppxPackage, 145 were Arm64, 54 were Neutral, 25 were X64, and 16 were X86.

I had assumed that the Store app layer on a Surface Pro 11th Edition running Windows 11 ARM64 would already be mostly Arm64. Instead, Arm64 accounted for 60.4%; 95 packages, or 39.6%, were non-Arm64. This is an inventory of registered packages rather than running processes, but nearly 40% was honestly a larger number than I expected.

The measurement and the JSON export were both created on July 25, 2026. The scope was limited to packages returned by Get-AppxPackage on this machine. It included OS components, Store apps, and runtime frameworks, which later made the mixed inventory harder to read.

The X64 and X86 entries also differed considerably from my pre-count impression. It does not look like a simple case of only old compatibility layers being left behind. Microsoft.PowerAutomateDesktop, Microsoft.AzureVpn, Microsoft.DirectXRuntime, Microsoft.OutlookDesktopIntegrationServices, Microsoft.WritingAssistant, and 1915OliverSchwendener.Ueli remained on the X64 side. The X86 side also contained Microsoft.DirectXRuntime and Microsoft.Ink.Handwriting.ja-JP.1.0.

Getting the data into JSON

At first I thought it would be enough to look at PowerShell's display output. In practice, Architecture is returned as an enumeration rather than a string, so reading only the visual output is risky. I expected strings such as X64 to appear directly, but that was not what happened. I switched approaches partway through and decided that counting after exporting to JSON would be safer.

Get-AppxPackage | Select-Object Name, Architecture, SignatureKind, IsFramework |
    ConvertTo-Json -Depth 4 |
    Out-File .ppx.json -Encoding utf8

This caused the first snag. Out-File -Encoding utf8 added a BOM, so Python's json.loads stopped at the beginning of the file. PowerShell's output looked normal, so it took a while to notice. I changed the reader to encoding="utf-8-sig" and loaded the file again. Not accounting for BOM-prefixed UTF-8 was the small but real failure in this run.

The other misunderstanding was the contents of Architecture. ConvertTo-Json emitted numbers rather than X86 or Arm64. On this machine, 0 corresponds to X86, 5 to Arm, 9 to X64, 11 to Neutral, 12 to Arm64, and 14 to X86OnArm64. I counted without checking that mapping, so the first result was just a list of 0, 9, 11, and 12. I could not explain why 12 was so common, and got stuck for a while.

import json
from collections import Counter

data = json.loads(path.read_text(encoding="utf-8-sig"))
arch = Counter(item["Architecture"] for item in data)

After fixing it, I converted the numeric enumeration values back to names before counting. Skipping that conversion can still produce a table, but it changes how the table should be interpreted. That is the dangerous kind of failure because no error is raised.

The architecture inventory

The architecture breakdown was as follows. Percentages are calculated against all 240 packages.

Architecture Count Share
Arm64 145 60.4%
Neutral 54 22.5%
X64 25 10.4%
X86 16 6.7%

Arm64 being the largest group is natural, but the 54 Neutral packages are also a large group. Items such as Microsoft.AccountsControl, Microsoft.Windows.CloudExperienceHost, Microsoft.Windows.ContentDeliveryManager, and Windows.PrintDialog are Neutral. They seem closer to resource- or host-oriented packages than executable binaries tied to one CPU instruction set.

I also counted signature types from the same data. Looking only at Architecture made OS components and Store packages look identical, and this second angle changed how I read the inventory.

SignatureKind Count Share
Store 124 51.7%
Developer 65 27.1%
System 51 21.3%

There were 51 System-signed packages, while the 124 Store-signed packages made up more than half. There were also 65 Developer-signed packages. This is not just an inventory of OS components; it contains a substantial mixture of Store and developer-signed packages installed in the user environment. It would be too much to read this table as the migration status of Windows itself. It is better understood as a snapshot that includes the app layer on this particular machine.

What remained as X64 and X86

Looking at the 25 X64 packages, many were runtime-related. The list included Microsoft.VCLibs.140.00, Microsoft.VCLibs.140.00.UWPDesktop, Microsoft.NET.Native.Runtime.2.2, Microsoft.NET.Native.Framework.2.2, Microsoft.UI.Xaml.2.8, Microsoft.WindowsAppRuntime.1.6, Microsoft.WindowsAppRuntime.1.7, Microsoft.WindowsAppRuntime.1.8, and Microsoft.WindowsAppRuntime.2. The inventory granularity is a little surprising if you are imagining only app executables.

Some recognizable app names were also present. Microsoft.Xbox.TCUI, Microsoft.OutlookDesktopIntegrationServices, Microsoft.AzureVpn, Microsoft.Limitless, Microsoft.PowerAutomateDesktop, and Microsoft.WritingAssistant were X64. MicrosoftWindows.Speech.en-US.1 and MicrosoftWindows.Speech.ja-JP.1 were also X64.

The 16 X86 packages were even more runtime-oriented, so saying only that old app binaries remained would again be insufficient. They included Microsoft.VCLibs.140.00, Microsoft.VCLibs.120.00.UWPDesktop, Microsoft.VCLibs.110.00.UWPDesktop, Microsoft.NET.Native.Framework.2.2, Microsoft.NET.Native.Runtime.2.2, Microsoft.UI.Xaml.2.7, Microsoft.UI.Xaml.2.8, Microsoft.WindowsAppRuntime.1.5, Microsoft.WindowsAppRuntime.1.6, Microsoft.WindowsAppRuntime.1.7, Microsoft.WindowsAppRuntime.1.8, and Microsoft.WindowsAppRuntime.2.

I realized afterward that X86 remaining does not immediately mean that an old app is running. Frameworks such as VCLibs and Windows App Runtime coexist in multiple architectures to match their dependent apps. There were 86 frameworks, or 35.8% of all packages. Counting this layer as if it were app executables can significantly distort the interpretation.

Microsoft.VCLibs.140.00 existed simultaneously as X86, X64, and Arm64. Microsoft.Services.Store.Engagement also appeared as X86, X64, and Arm64. One package name can therefore be installed in multiple architectures; counting only distinct package names would miss part of the situation.

Where it failed

The failure was mundane: I thought I could look at PowerShell's text output and finish by parsing it casually. I treated something readable on screen as if it were automatically suitable as data. But ConvertTo-Json introduced two traps: the BOM and numeric enumeration values.

The BOM was easy to understand because Python's json.loads failed at the beginning. Looking at the file as binary would reveal the cause, so this was the more helpful kind of failure. Changing to utf-8-sig made it readable.

The Architecture issue took longer. The counts came out as 12, 11, 9, and 0 and looked plausible. I should have stopped to ask why they were numbers rather than names, but I nearly turned them into a table unchanged. Even when the numbers are correct, the whole table is broken if their meaning is wrong.

I kept the mapping in the JSON's arch_enum_map: 0=X86, 5=Arm, 9=X64, 11=Neutral, 12=Arm64, and 14=X86OnArm64. Writing that mapping into the article too means that when I revisit the data later, I can remember why 12 was the largest group. It is also a note for my future self.

Why counting matters

In my experience, people tend to describe the ARM64 Windows migration from feel. When the apps used every day work normally, it can feel as if native support is already far along. Conversely, one heavy X64 app can make the migration seem unfinished. Experience alone swings too far in either direction.

These 240 packages show the middle ground. Arm64 is the majority at 145 packages. But there are also 54 Neutral, 25 X64, and 16 X86 packages, for 95 non-Arm64 packages in total. Even the Store app layer still contains a block approaching two-fifths that is not native.

I now treat runtime packages as a separate category when looking at this number. Multiple architectures of Microsoft.WindowsAppRuntime and Microsoft.VCLibs are closer to compatibility inventory than a bad sign. If actual app names such as Microsoft.PowerAutomateDesktop or Microsoft.AzureVpn remain X64, however, I would like to measure their startup behavior and emulation impact separately.

This inventory measured how far native migration has progressed on this machine without relying on feel. The next step is to compare registered packages with processes that actually started. The packages that remain registered and the programs that consume CPU time every day probably do not have the same ratio.

Architecture Operations PowerShell
a
arm64lab — Independent publisher

Personal test notes from a Surface Pro 11th Edition with Snapdragon X Elite, used as a daily machine since May 2025. Results are based on direct measurements and do not represent any company or organization.