Skip to content

Porting a Windows App to Arm64: The Complete Path

Updated Jun 5, 2026

A native Arm64 build is the difference between your app sipping battery at full speed and crawling through Prism emulation. It also unlocks what emulation can’t do at all: kernel drivers, shell extensions, deep hardware integration. Here’s the complete path from x64-only to shipping native Arm64.

Step 1: Audit your dependencies first

This is the step that makes or breaks the port, and it comes before you touch a single build setting. Every static lib, NuGet package, native DLL and plugin your app loads must have an Arm64 (or ARM64EC) build. Walk the full dependency tree. One x64-only native dependency with no Arm64 release and no replacement is the signal you’ll need ARM64EC rather than a pure Arm64 port. Look your dependencies up in our catalog to see which already ship native.

Step 2: Add the ARM64 solution platform

In Visual Studio (use 2022 17.4+): Configuration Manager → Active solution platform → <New...> → select ARM64, copy settings from your existing x64 platform, keep “Create new project platforms” checked. Your project now has an Arm64 target.

Step 3: Install the Arm64 build tools

Through the Visual Studio Installer, add the Arm64 build tools (MSVC Arm64 compiler/libraries). You don’t need an Arm device to build — Visual Studio cross-compiles to Arm64 from an x64 machine.

Step 4: Build natively or cross-compile

Two valid setups:

  • On-device (native): develop on a Snapdragon X laptop — you get local debugging and can run your test suite on-target.
  • Cross-compile (x64 host): faster and cheaper, but you can’t run the result locally — you’ll set up remote debugging to an Arm device or VM.

The pragmatic CI pattern is cross-compile on x64 + a native Arm64 job for tests; see the CI/CD guide.

Step 5: When a dependency blocks you → ARM64EC

If an essential dependency is x64-only and can’t be swapped, you don’t have to stay fully emulated. ARM64EC lets native Arm64EC code and emulated x64 code share one process — recompile your hot paths natively while the stubborn x64 dependency keeps running. Full detail in the ARM64EC deep dive.

Step 6: Verify and ship

Confirm the build is genuinely native — Task Manager’s Architecture column should read ARM64 (see how to check). Then publish: the moment your Arm64 build lands on winget, the Microsoft Store, or GitHub Releases, compatibility trackers like ours detect it and flip your entry to native. Browse the native-app catalog and the native-share trend to see the ecosystem you’re joining.

The decision tree

  • All dependencies have Arm64 builds → pure Arm64, best outcome.
  • One or two x64-only dependencies, no replacement → ARM64EC, incremental.
  • A blocking kernel-driver dependency → that’s a driver port, a separate effort.

← All guides