.Net Development on the M1 Mac

Maarten Merken
7 min readNov 11, 2021

--

I switched to a MacBook about 2 years ago, I’m a Software Engineer in .NET and Angular.

Since .NET (Core) is cross-platform, I decided to switch things up a bit, and once Apple introduced their new in-house ARM-based silicon, I was eager to try it out.

This is how I managed to setup my M1 MacBook Air for .NET and Angular (NodeJS) development.

The state of .NET on Apple ARM64

When the M1 chip came out, it was already possible to install the runtime (or even the SDK) of .NET Core 3.1 (and lower) and have it compile and run applications. This just worked using Rosetta:

dotnet myapp.dll

Debugging, however, was an entire different story. The dotnet team and Apple were in close contact in order to smooth out bugs in Rosetta. You could join the Big Sur beta program in order to get these fixes early on.

The latest Big Sur release fully supports running and debugging .NET Core applications (including .NET 5). The performance of .NET under Rosetta was impressive, but it wasn’t orders of magnitude faster than running on Intel.

With .NET 6 on ARM, however, we can see significant improvements in application startup times, ASP.NET response times and general test execution times overall.

When the M1 first came out, Youtuber Alexander Ziskind did a comparison between .NET 5 on Intel vs M1

The Intel i9 MBP outperformed the M1 by a small margin, keep in mind that .NET 5 was running through Rosetta translation.

I retried this test on my M1 using .NET 6 on ARM and these are the results:

47 seconds consistently, not bad considering that the i9 did about 57 seconds and the M1 did about 60 seconds (using Rosetta).

For those who are interested in the benchmarking code, here’s the C# 10 variant of it:

using System.Runtime.CompilerServices;using System.Security.Cryptography;for (int i = 0; i < 100_000_000; i++){    Consume(CryptoConfig.CreateFromName("RSA"));}[MethodImpl(MethodImplOptions.NoInlining)]static void Consume<T>(in T _) { }

So, if your workflow exists of pure .NET Core, or .NET 5 or 6, you’ll be happy using your M1 machine for development.

IDE: Integrated Development Environment

When the M1 first came out, most of our toolset relied on the Rosetta 2 translation layer in order to run x86-based applications on the ARM architecture.

This included VS Code, Visual Studio for Mac, JetBrains Rider, Omnisharp, Mono…

The experience was awful on all of them, they’d get the job done eventually, but I wasn’t ready to retire my i7 MacBook Pro anytime soon.

The ARM-based versions of these IDE’s came out gradually, apart from Visual Studio for Mac, all of my workflow can now be run on Apple Silicon natively.

So what’s the status quo for .NET development on M1 in November 2021?

Visual Studio for Mac

I mean, it works?

To understand where Visual Studio for Mac came from, you must first understand MonoDevelop. MonoDevelop is a cross platform IDE for building .NET applications using the Mono framework. It has been around for some time. Visual Studio for Mac is a spin-off this technology. Since there are no plans from Microsoft to port this to native Apple Silicon (ARM64), you’re stuck with Rosetta emulation.

I’ve tried my best to use Visual Studio for Mac, I really did. For small projects, sure, you could give it a shot. But for my 40+ project solution, it just was not performant enough.

However, do not fret, for support on M1 is coming in the future, stay tuned!

VS Code

VS Code was the first IDE to be ported to ARM64 Apple Silicon, mostly due to it was already ported to Raspberry Pi ARM.

You can get the Apple Silicon optimised version of VS Code today. Most of the extensions have been ported to ARM64 and most of all, Omnisharp has been ported to darwin-arm64, too!

VS Code is the best free alternative to develop .NET applications on Apple Silicon. However, VS Code is a code editor, a very capable one. But for professional development you might need an actual IDE.

JetBrains Rider

Let me be blunt, Rider is the best cross-platform IDE for .NET development to date.

Even on Rosetta emulation, Rider was far more performant than Visual Studio for Mac. They were prompt to adopt Apple Silicon, releasing an EAP (early access preview) free of charge in order to test out Rider running natively on ARM64.

Tip: if you want to download the most stable build of Rider, add the following to the download URL : ‘-aarch64.dmg’.

For example: https://download.jetbrains.com/rider/JetBrains.Rider-2021.2.2-aarch64.dmg

If you just want to try out Rider, you can get the EAP version here: https://www.jetbrains.com/rider/nextversion/

Select the Apple Silicon version to download.

This version of Rider comes with its own version of .NET 6 for ARM, you can still install other .NET Core sdks on your system (like .NET Core 3.1). This will run under Rosetta when debugging, Rider is capable of spawning, attaching and terminating these processes, making this the most flexible IDE for .NET Core development to date!

Virtualisation and Emulation: Windows on ARM

Sometimes, as .NET developer, you just need to run a Windows executable on macOS.

For instance, my workflow contains of running an old x86 executable that was built years ago on Windows. This executable is used throughout the company to transform a file from a legacy format into an xml-based format. Many teams use this executable and is has not been modified for years. Porting it to .NET Core was out of scope.

VirtualBox

At the moment, there’s no support to run a Virtual Machine through VirtualBox.

VMWare

VMWare announced a preview version of VMWare Fusion, this allows you to run an ARM-based Virtual Machine. There are some limitations, though. For instance, you can’t get shared networking or shared clipboard to work due to the lack of VMWare Tools for ARM.

UTM

UTM is emulation software and runs on top of QEMU.

Link to tutorial: https://jensd.be/1533/windows/windows-11-arm-on-m1-based-macs-with-utm

Parallels

Parallels is paid software, but in my opinion, it is worth the money if you need a Windows Virtual Machine on macOS. The performance is industry leading and the integration with macOS is sublime. I encourage you to install the trial and see for yourself.

Windows on ARM

Once you’ve picked your virtualisation software above, you’re ready to start with Windows on ARM. Download the Insider Preview from Microsoft and use that virtual hard disk as the starting point for your VM.

After installing Windows 11 on ARM, you may want to activate it, you can do this with any valid Windows 10 license key. But first, make sure all your required software runs smoothly!

x86 applications are emulated on Windows on ARM, so you could technically install Visual Studio for Windows, .NET Framework 3.5 or 4.7, and start developing your WPF applications on that VM. I’ve done this, it works, but it’s not performant. However, I mean, if you occasionally need to handle this kind of workflow, sure, you could give it a shot.

The bottom line is, do not get a Mac for Windows WPF or .NET Framework development.

What about running a x86 Virtual Machine under emulation?

I tried this, using UTM and QEMU, the experience is not pretty. I can’t recommend this approach to anyone.

Docker

Docker (containerisation) is one the most versatile tools and skill you can learn in this decade, so you’ll be happy to hear that this just works on your Apple M1 machine.

Running ARM-based Linux containers

There’s lots of ARM64-based images on Docker hub, mostly thanks to the Raspberry-pi community. Running these containers just work on the M1.

Running x86-based Linux containers

Most of the official docker images are supported to run under AMD64 emulation. This is basically Docker emulating (using QEMU) the container on ARM64.

For instance, if you’d like to run the MySQL x86_64 image on your M1 you’d use:

docker run --platform linux/amd64 mysql/mysql-server:latest

This will spin up a MySQL server container using emulation.

Performance may vary, but when possible, try to find an ARM64 based counterpart for this image, if you can find any.

For MySQL, this is MariaDB

For MSSQL server, this is Azure-Sql-Edge

Running Windows containers

You need a Windows host for this, I do not recommend nested virtualisation, like Parallels, for this. If your workflow requires you to spin up these kind of containers, you’re out of luck on Apple Silicon.

Memory usage and Swap

You might have heard that these M1 ARM chips have got some serious swapping going on, turns out that macOS itself loves to use swap, even if there’s still enough free RAM available.

Turns out, this was nothing to worry about, since Apple fixed these swapping issues update after update.

If you do worry about swap and the lifetime of your SSD. I’d say, skip out on the M1 MAX and invest in RAM first, and SSD second when getting a new M1 MacBook Pro.

Also, try to avoid using apps that require Rosetta translation, this will reduce swap dramatically.

In closing

I’ve been using my M1 MacBook Air with 16GB RAM for over a year now, it has lately replaced my 16" MacBook Pro 2019 i7 5300M 32GB RAM. I enjoy the aesthetics of the Air and mostly the portability, whilst matching, sometimes excelling the performance of the Intel-based machine. For the moment I get by using 16GB of RAM. Once this falls short, I’ll look into getting an M1 Pro.

--

--