Introduction
Man, choosing a tool for developing cross-platform Xamarin apps on a Mac used to be so easy. Microsoft had our backs with Xamarin Studio, and later with Visual Studio for Mac.
Recently though, Microsoft decided to add a little twist!
Yes, the Xamarin MVP Monkey is giving us all a dramatic goodbye… 😢
And Visual Studio for Mac is going with it. 🎹🎹 Yep, you heard that right: Visual Studio for Mac 17.6 will ride off into the sunset on August 31, 2024.
Microsoft’s decision to retire the IDE isn’t unsurprising: The company is focusing on developing the .NET MAUI framework, the successor of Xamarin.Forms.
But fear not, dear developers, because Microsoft has a plan. 😉
They’re doubling down on Visual Studio Code as the go-to coding tool for Mac users. It’s like saying goodbye to your trusty old car and hopping into a shiny new rocket ship!
But there are other options that might just become your preferred development environment. So in this article, we’ll explore these options.
Also, if you haven’t checked out our guide for migrating Xamarin.Forms applications to MAUI yet, we recommend you take a look to ensure a smooth migration journey.
So strap in folks, because the MAUIverse is calling. 🚀
MAUI on Mac: your options
Alright, it’s time to check out the tools!
We’ll be covering three viable options for developing our .NET MAUI applications:
- The .NET MAUI extension in Visual Studio Code for Mac
- JetBrains Rider for Mac
- Using the command line tools on Mac (with an editor of your choice)
In this post, we’ll look at how to set up all options, their usage, and their pros and cons. After all, with great tools comes great responsibility (and maybe a few bugs too!).
In particular, we’ll go through the following for each option:
- Installation
- Creating a new project
- Running and debugging
- Using the NuGet package manager
Let’s start with the .NET MAUI extension in Visual Studio Code, which is the option recommended by Microsoft.
.NET MAUI extension in Visual Studio Code
The .NET Multi-Platform App UI (MAUI) extension is the gateway to the MAUI realm for Visual Studio Code users on Mac. It comes with all the necessary tools for developing cross-platform apps.
With the ability to develop and debug your creations on various devices, emulators, and simulators directly within VS Code, Microsoft aims to replicate the seamless experience of Visual Studio for Mac.
The .NET MAUI extension is built on top of the powerful C#, C# Dev Kit and .NET Install Tool extensions, which gives you:
- IntelliSense
- An intuitive solution explorer
- Package management and project references
- Debugging
- Unit tests
- …and more!
💡 Installing the VS Code .NET MAUI extension also automatically installs the C#, C# Dev Kit and .NET Install Tool extensions as dependencies.
⚠️ Keep in mind that the .NET MAUI extension is still in preview. It therefore has some limitations and kinks to work out.
C# Dev Kit and C# extensions
C# Dev Kit is an extension designed to enhance your coding experience. Among other things, it gives you a solution explorer to navigate your code in the IDE as well as integrated unit test discovery and execution to ensure your code is test-driven.
This extension builds on the powerful C# language capabilities provided by the C# extension. C# Dev Kit’s tools and utilities integrate natively with VS Code and help developers to write and debug code faster, to avoid errors, and to simplify maintenance.
💡 C# Dev Kit is free for individuals, academia, and open-source development. For organizations, it’s included with Visual Studio Professional and Enterprise subscriptions.
Installation
Visual Studio Code is a lightweight but powerful source code editor. It comes with built-in support for JavaScript, TypeScript and Node.js and has a rich ecosystem of extensions for other languages and runtimes (such as C++, C#, Java, Python, PHP, Go, .NET).
- Download VS Code and install it.
- Download .NET and install it (make sure you download the right file for Apple Silicon machines).
- In Visual Studio Code, install the .NET MAUI extension. This will also install C#, C# Dev Kit and .NET Install Tool as dependencies.
For iOS/macOS development:
- We need to install Xcode for its SDK and simulators. Downloading Xcode requires an Apple ID.
- Download and install Xcode.
- Install the Xcode command line tools with the following command:
xcode-select --install
- Launch Xcode. On the first open it will ask you to set up the iOS Simulator, so let’s do that.
Your iOS setup is now ready to run on simulators. However, to run the app on your device, you will need a valid certificate and provisioning profile (you can find more information here).
For Android development:
- Install Microsoft OpenJDK 17. Older JDK versions can cause issues and are therefore not recommended.
- During the installation, JDK will prompt you to install Rosetta (if not already installed).
- After installing JDK, create a new project and install the Android SDK using the following command:
sudo dotnet build -t:InstallAndroidDependencies
-f:net8.0-android
-p:AndroidSdkDirectory=/Users/MyLocalFolderName/Library/Android/sdk
-p:JavaSdkDirectory=/Library/Java/sdk
-p:AcceptAndroidSDKLicenses=True
In this command,AndroidSdkDirectory
specifies where to install the Android SDK (e.g.,/Users/MyLocalFolderName/Library/Android/sdk
) andJavaSdkDirectory
where to install the Java SDK (e.g.,/Users/MyLocalFolderName/Library/Java/sdk
).
💡 Another approach is to use Android Studio to manage the SDK, APIs, tools, emulators, debug options, logs, etc. This requires some environment variable setup.
- Restart VS Code and check out the
Output
tab, which gives you information about the Android and iOS/macOS SDK status. - Now you have to accept the license for your Android SDK.
In VS Code, press Cmd + Shift + P, select“.NET MAUI: Configure Android”
, and you should get an option to accept the license. Alternatively, restart your project, and you’ll be prompted to accept the license via the command line. - Set the JDK and Android SDK paths as well. In VS Code, press Cmd + Shift + P and select the option
“.NET MAUI: Configure Android”
Now you should be able to run it on your Android device.
- Finally, we need to install the .NET MAUI workloads with the following command:
dotnet workload install maui
Creating a new project
We will create our first Visual Studio Code demo application using the .NET MAUI extension as follows:
- Click the
Create .NET Project
button or press Cmd + Shift + P - Select
.NET: New Project
- Select the project template
.NET MAUI App
- Select a project directory
- Enter the project name and submit
- Confirm
Create Project
- If your project gets a build time error regarding the .NET MAUI tools, use the following command to install the necessary workloads:
dotnet workload restore
Running and debugging
- On the bottom toolbar in Visual Studio Code, you will see the toolbar item “
{ }
” .
With this, you can check the current target configuration. - Through the “
{ }
” button, you can also update the startup project and the target device options. - After selecting the configurations, you can simply press F5 to run the project. You can also open the
RUN AND DEBUG
tab from the side panel of VS Code and click on theRun and Debug
button. - Debugging is similar to what we had in Visual Studio for Mac, like setting the breakpoints in the code.
- Changing the configuration from Debug to Release mode isn’t supported yet. However, you can do that by adding a custom configuration in a
launch.json
file. After adding these configurations, you can use them from theRUN AND DEBUG
tab.
Thelaunch.json
file is created locally in the.vscode
folder. Here is what the configurations look like:"configurations": [
{
"name": "Developer",
"type": "maui",
{
}
]
Package management & project reference
NuGet package manager:
Visual Studio Code doesn’t really have a full-fledged NuGet package manager GUI like Visual Studio for Mac does. But there are some alternative options.
Restoring the packages:
- You can set Automatic NuGet restore to ON. VS Code will now restore the packages automatically if the project is missing them.
Visual Studio Code -> Settings -> Extensions -> C# -> LSP Server -> Dotnet -> Enable Automatic Restore
Alternatively, go toVisual Studio Code -> Settings
and search for the following text:”dotnet.projects.enableAutomaticRestore”
This is the option we’re looking for:
- The other option is to use the command line to restore the packages. We’ll look at this in the next section.
- To change or update the NuGet source, you have to modify the
Nuget.Config
file directly, which you can find at/Users/<username>/.config/NuGet.Config
.
Adding NuGet packages and project references:
Adding, removing, and updating packages is easy. It’s not like the NuGet package manager window in Visual Studio for Mac, but it does the job.
- To add a NuGet package or a project reference, go through the Solution Explorer context menu like so:
VS Code File Explorer -> Solution Explorer -> Expand Solution -> Right Click on the project
- To remove/update a NuGet package, you can expand the project dependencies and navigate to the exact package.
- To remove a project reference, you have to directly edit the .csproj file, e.g.:
<ItemGroup>
<ProjectReference Include="..\..\FirstClassLibrary.csproj" />
</ItemGroup>
JetBrains Rider
I believe this GIF adequately portrays Rider’s power. But will you be able to handle it?
JetBrains Rider is a full-fledged cross-platform .NET IDE providing a complete environment for developing .NET MAUI apps.
Rider works with a wide variety of .NET Framework, Mono, and .NET Core project types. It supports most languages used in .NET development, including C#, VB.NET, F#, ASP.NET syntax, XAML, XML, JavaScript, TypeScript, JSON, HTML, CSS, and SQL. Its large set of powerful features that also work across different languages lets you deliver quality code faster than ever.
All this makes it the best choice for replacing Visual Studio for Mac.
One important thing to note, however, is that JetBrains Rider requires a paid subscription.
Highlights:
- More stable and reliable compared to Visual Studio for Mac.
- Eliminates a lot of the annoyances of developing .NET MAUI apps in Visual Studio for Mac.
- A full-fledged IDE, unlike the .NET MAUI extension for VS Code.
- The decompiler allows you to jump directly into the third-party package/code in your project, even from a particular XAML class implementation (e.g., Label).
- Powerful IntelliSense code completion, refactoring, debugging, version control and more.
- Convenient shortcuts that increase productivity, a bunch of different IDE settings, and more.
Installation
- Download JetBrains Rider here and follow the general macOS application installation process.
- For iOS/macOS development, we must install Xcode.
- For Android, we need to install Microsoft OpenJDK 17 and Android Studio.
Initial JetBrains Rider settings
For Android development:
- After installing Android Studio to get the Android SDK, launch JetBrains Rider.
- Install the
Rider Android Support
plugin to get started with Android:JetBrains Rider -> Settings -> Plugins -> Install "Rider Android Support"
- After installing this plugin, a new tab will show up in the JetBrains Rider settings:
JetBrains Rider -> Settings -> Build, Execution, Deployment -> Android
Here, set the paths for theAndroid SDK
and theMicrosoft Open JDK 17
.
Make sure the developer options are enabled on your Android device. This completes the setup for Android development, so your app is ready to roll on your device.
You also have the option to create and launch an emulator from Android Studio.
For iOS development:
- Install Xcode, then launch it to download/install the iOS simulators.
- Now launch JetBrains Rider and set the Xcode path:
JetBrains Rider -> Settings -> Build, Execution, Deployment -> Apple Platforms
After doing this, your iOS setup is complete, and your iOS app is also ready to roll on the simulator. To run the app on your iOS device, however, you will need a valid certificate and provisioning profile (you can find more information here).
Alright! Then let’s dive into creating a new application with Rider.
Creating a new project
Creating a new project is similar to Visual Studio for Mac: Just create a solution and select a project template.
Running and debugging
In Rider, there are separate sections for selecting a platform configuration, be it Android or iOS. The device and simulator/emulator lists are populated depending on the platform.
For debugging, select the debug button in the bottom left of the IDE window.
NuGet package manager
Rider integrates a simple interface for the NuGet package manager. It provides a good interface for search filters, adding/selecting custom sources, and logs, installation of packages for multiple projects at once, and more.
You can also right-click on the project and select Manage NuGet package
, which will open this tab at the bottom.
The buttons on the left allow you to restore/download, update, refresh packages and much more.
.NET CLI on Mac
For the elite developers who prefer flexing their CLI muscle over relying on fancy IDE magic and crave results based solely on their precise inputs rather than any third-party influence, we raise a digital salute. 🫡
I call those people Terminal Ninjas. With unwavering confidence in their commands, they bend the CLI to their will. If you’re among them: Kudos! Let’s get started.
Just like the other options, this one also has its pros and cons. It might take a bit of R&D until you find all the necessary commands needed for your development process.
Installation
- Download the .NET SDK here and install it.
- Install the .NET MAUI workload by using this command in the terminal (with or without
sudo
, depending on your privileges):dotnet workload install maui
- To verify the workload installation, use the following command:
dotnet workload list
For developing iOS/macOS and Android applications, we need to do the following:
- For iOS/macOS development, install the Xcode tool for SDK and simulators.
- For Android development, install the Microsoft OpenJDK and Android Studio for the Android SDK and emulators.
For the individual iOS and Android setup steps, please refer to the .NET MAUI extension section above.
Creating a new project
Let’s jump into all the core commands you’ll need:
- For creating a new project, the basic command is:
dotnet new maui
Here,maui
is the template for MAUI projects. Typically, you’ll do this after some basic preparation, like creating a directory for the project:mkdir FirstCLIApp
cd FirstCLIApp
dotnet new maui
This series of commands creates a new project based on the template maui
in the directory name FirstCLIApp
. So by default your solution will be created as FirstCLIApp.sln
, which will have a MAUI project named FirstCLIApp.csproj
.
- For setting a project name, use the following command:
dotnet new maui -n "FirstCLIApp"
- To check out all available project templates for a project, you can use this command:
dotnet new list
For more parameters you can use while creating a project, see below. You can find further details in the Microsoft docs.
dotnet new <TEMPLATE>
[--dry-run]
[--force]
[-lang|--language {"C#"|"F#"|VB}]
[-n|--name <OUTPUT_NAME>]
[-f|--framework <FRAMEWORK>]
[--no-update-check]
[-o|--output <OUTPUT_DIRECTORY>]
[--project <PROJECT_PATH>]
[-d|--diagnostics]
[--verbosity <LEVEL>]
[Template options]
Running and debugging
In this section, we will look at the commands related to restoring, building and running the project. For the full command reference, check out the .NET CLI docs.
- Restore packages: Restores the dependencies and tools of a project.
dotnet restore
- Build: The following command will restore the project dependencies and build the app.
dotnet build
- Run: The following command will restore the project dependencies and build the app.
dotnet run
We can run the above commands without any parameters, but that sets them to their default values, which aren’t always what we need. So let’s jump into some use cases.
iOS simulator:
dotnet build
-t:Run // target
-f net8.0-ios // framework
-p:_DeviceName=:v2:udid=<MY_SPECIFIC_UDID> // property
Here, the .NET MAUI iOS app is launched on a particular simulator by passing the simulator’s unique identifier. There are two ways to get the identifier:
Using Xcode:
Xcode -> Windows -> Devices and Simulators -> Right-click on the simulator -> Copy Identifier
Or using the command line (the following command prints all the devices in the terminal along with their identifiers):
/Applications/Xcode.app/Contents/Developer/usr/bin/simctl list
iOS device:
With the developer mode enabled on your iPhone or iPad, use the following command:
dotnet build
-t:Run // target
-f net8.0-ios // framework
-p:RuntimeIdentifier=ios-arm64 // property
-p:_DeviceName=<MY_SPECIFIC_UDID> // property
You can retrieve the device identifiers in the same way as the simulator identifiers.
Android emulator/device:
The following command works for both devices and emulators. If you use a device, make sure that developer mode is enabled.
dotnet build
-t:Run // target
-f net8.0-android // framework
Finally, on the topic of debugging: When using the command line, debugging gets more complicated. It’s a huge topic that deserves an article of its own, so we won’t cover it here.
NuGet package manager
These are the commands used frequently to manage NuGet packages:
- Restore the packages and tools for the project:
dotnet restore | dotnet restore <PROJECT_FILE>
- Clear the local NuGet cache:
dotnet nuget locals all --clear
- Add/remove a package:
dotnet remove [<PROJECT>] package <PACKAGE_NAME>
dotnet add [<PROJECT>] package <PACKAGE_NAME>
There are many other important aspects, such as adding/removing/updating/disabling a custom source.
- Add a NuGet source:
dotnet nuget add source <PACKAGE_SOURCE_PATH>
- Remove a NuGet source:
dotnet nuget remove source <NAME> [--configfile <FILE>]
- Enable or disable a NuGet source:
dotnet nuget disable source <NAME> [--configfile <FILE>]
dotnet nuget enable source <NAME> [--configfile <FILE>]
- Update a NuGet source:
dotnet nuget update source <NAME>
- Display a list of all available NuGet sources. It reads from the global Nuget.Config file:
dotnet nuget list source
Short comparison
Based on our own usage, we would like to provide feedback for the tools discussed in this article. As the command line approach is not a tool per se, we will only compare the .NET MAUI extension for Visual Studio Code and JetBrains Rider.
Rating factors | .NET MAUI extension | JetBrains Rider |
---|---|---|
IntelliSense / editor | ★★★★★ | ★★★★★ |
Solution explorer | ★★★ | ★★★★★ |
Decompiler & navigation | ★★ | ★★★★★ |
Running and debugging | ★★★ | ★★★★★ |
Package manager | ★ | ★★★★★ |
Project ref. management | ★ | ★★★★★ |
Feature richness | ★★★ | ★★★★★ |
Free of charge? | ✔️* | ❌ |
Elaboration on some points
Solution explorer:
The solution explorer in Rider offers more features and settings compared to the VS Code .NET MAUI extension. It’s also more interactive.
Running and debugging:
The run-and-debug experience in Rider is superior, with more configuration options and an easy-to-use interface. For example, you can see the list of simulators and devices separately, unlike in the VS Code .NET MAUI extension.
Decompiler & navigation:
One very helpful feature in Rider is that you can navigate to the class declaration directly, even if it is a third-party library. Other than that, code navigation is similar in both.
Package manager:
The package manager in the VS Code .NET MAUI extension is very basic: You can just add/update/remove a NuGet package. But inside Rider, you get a dedicated tool where you can add/update/remove NuGet packages as well as NuGet sources.
Project reference management:
Project reference management is very easy in Rider. If you’re using the VS Code .NET MAUI extension, you have to manually add and remove references.
Feature richness:
Rider is a full-fledged IDE, so it has many more features compared to the VS Code .NET MAUI extension.
Pricing:
Rider is paid software. The VS Code .NET MAUI extension depends on the C# Dev Kit extension, which is free for individual, academic, and open-source developers. Enterprises will need a Visual Studio Professional subscription.
Recommendation
We hope this comparison of the currently available Visual Studio alternatives for Mac helped you choose the best option for developing .NET MAUI applications.
We’d like to leave you with the following advice:
- If you prefer a fully fledged, powerful IDE, go with JetBrains Rider.
- If you prefer to have a combination of a lightweight IDE and the CLI, then the .NET MAUI Extension in VS Code is your best bet.
- If you don’t want to rely on anything but your commands, then go with the CLI. However, this option still requires a good editor, which in most cases will be VS Code.
Good luck in selecting your approach and happy coding!