Cross-Platform Mobile App Development with .NET MAUI
.NET MAUI (Multi-platform App UI) — direct successor to Xamarin.Forms, rewritten for .NET 6+. The main architectural change: one project instead of separate iOS, Android, WinUI, macOS targets — everything through a single csproj with conditional dependencies per platform. This means one appsettings.json, one DI container (Microsoft.Extensions.DependencyInjection), one set of models.
If your team already works with C# and ASP.NET Core, transition to MAUI is technically minimal — patterns are the same, tooling is the same (Visual Studio 2022 / Rider), NuGet is the same. For enterprises where a mobile application is a frontend to a .NET backend, this is often the only reasonable choice from a team unification perspective.
Where real problems arise
MAUI renders native platform controls through Handlers — unlike Xamarin.Forms with Renderers. On paper this is cleaner. In practice: if a standard Handler doesn't support the needed property, we write a partial class with platform-specific code and AppendToMapping. This is a normal pattern but requires understanding native APIs of each platform.
Hot Reload works with caveats. XAML Hot Reload in Visual Studio 2022 17.6+ works well for simple markup changes. But changes in C# code-behind or view model require restart — .NET Hot Reload in MAUI is unreliable with complex hierarchies. In practice UI iteration takes more time than in Flutter or React Native.
Binary size. Base .NET MAUI app APK without trimming — 30–50 MB. With PublishTrimmed=true and RuntimeIdentifier=android-arm64 we can compress to 15–25 MB, but trimming breaks Reflection, which many NuGet packages rely on. Each added package must be checked for AOT/trimming compatibility.
NativeAOT on iOS — available with .NET 8. Gives better startup time and size, but requires complete abandonment of runtime Reflection. If a project uses System.Text.Json with source generators — okay. If Newtonsoft.Json — migration is mandatory.
Stack and architecture
MVVM — standard for MAUI. CommunityToolkit.Mvvm covers 90% of needs: [ObservableProperty], [RelayCommand], [NotifyCanExecuteChangedFor] via source generators. No INotifyPropertyChanged boilerplate manually.
Shell navigation (Shell) for standard cases; for complex navigation with object passing — NavigationPage or ReactiveUI.Maui. Prism.Maui — if the team is familiar with it from WPF/UWP.
Network layer — HttpClientFactory via DI, Refit for typed REST clients, Polly for retry/circuit breaker. gRPC client via Grpc.Net.Client works on iOS and Android without additional setup starting with .NET 7.
Local DB — SQLite-net-pcl for simple cases, LiteDB for document-oriented storage. Entity Framework Core with SQLite provider works, but in trim scenario requires EFCore.TrimmingSupport.
Push notifications — Plugin.Firebase.CloudMessaging for FCM; APNs on iOS configured via UNUserNotificationCenter in MauiProgram.cs.
Real case. Corporate app for field inspectors: offline work with forms and photos, sync when network appears. Stack: MAUI + EF Core SQLite + Polly for retry queue + Xamarin.Essentials (now Microsoft.Maui.Essentials) for camera and GPS access. Platform-specific part — only filesystem work (paths differ on iOS Documents vs Android GetExternalFilesDir). CI — Azure DevOps Pipelines with dotnet publish tasks per platform, signing via KeyVault for Android keystore.
Platform integration
Native API access — via Microsoft.Maui.Essentials: geolocation, accelerometer, Bluetooth, camera, biometrics (SecureStorage + Fingerprint). For access beyond Essentials — DependencyService with platform-specific implementations or direct native code calls via #if ANDROID / #if IOS in partial classes.
Native SDK bindings: on Android — Java/Kotlin Binding Library via Binding Project; on iOS — ObjectiveC/Swift Binding via ApiDefinitions.cs. The procedure is labor-intensive but well-established.
Timelines
| Scope | Timeline |
|---|---|
| Corporate MVP, 8–12 screens | 8–14 weeks |
| Product with offline and sync | 4–7 months |
| Platform with corporate system integration (SAP, 1C) | 6–12 months |
Cost calculated individually after analyzing requirements and customer's existing .NET infrastructure.
What we focus on during audit
Three things we see often in inherited MAUI projects: lack of trimming compatibility (app weighs 60+ MB), use of deprecated Renderer from Xamarin.Forms instead of switching to Handler, and synchronous DB operations on UI thread via EF Core without async/await. The last one — guaranteed ANR on Android.







