Skip to main content

Dev Station Technology

React native web development

Mastering React Native Web Development: The Ultimate Guide

TL;DR. Xamarin lets C# developers ship native iOS, Android, and Windows apps from a single codebase. This guide covers the platform architecture, the trade-offs between Xamarin.Forms and Xamarin.Native, code-sharing strategies, UI development patterns, testing workflows, and deployment pipelines so you can decide whether Xamarin fits your next mobile project.


Why Xamarin Still Matters for Cross-Platform Mobile Development

Xamarin, acquired by Microsoft in 2016 and now part of the .NET ecosystem, compiles C# into native ARM binaries for iOS and Android. Unlike hybrid frameworks that wrap a WebView, Xamarin provides direct access to native platform APIs while letting you share business logic, networking code, and data models across platforms. The result is native performance with a single-language codebase.

With .NET MAUI succeeding Xamarin.Forms, the original Xamarin SDKs remain in maintenance mode, but thousands of production apps still run on them, and the architectural patterns Xamarin introduced carry directly into MAUI. Understanding Xamarin is a prerequisite for maintaining those apps and for making informed decisions about migration.

1M+

Active Xamarin developers worldwide

90%+

Code sharing achievable across platforms

Native

Compilation to platform ARM binaries

C# / .NET

Single language and runtime stack


Xamarin Architecture

Xamarin apps run on the Mono runtime on non-Windows platforms. On iOS, the Ahead-of-Time (AOT) compiler translates C# into native ARM code that Apple’s App Store accepts. On Android, the Mono runtime sits alongside the Dalvik/ART runtime, and C# code calls Java libraries through JNI bindings that Xamarin generates automatically.

Shared Code Layer

Business logic, data access, view models, and networking live in a shared .NET Standard or .NET library project. This layer has zero platform-specific references.

Platform Bindings

Xamarin.iOS and Xamarin.Android provide 1:1 bindings to the full native SDK. Any API available in Swift or Kotlin is accessible from C# with the same signature and semantics.

Mono Runtime

On iOS, AOT compilation eliminates the JIT at runtime. On Android, the Mono VM co-exists with the ART VM, and Xamarin’s JIT handles dynamic code paths while still supporting AOT for startup performance.

Platform Projects

Each target (iOS, Android, Windows) has its own head project with platform-specific UI, startup code, and dependency registration. These projects reference the shared layer.

Key Insight: Xamarin does not interpret or wrap a WebView. The C# compiler produces the same native instructions as Swift or Kotlin compilers. The Mono runtime is only needed for garbage collection and platform abstraction, not for executing your code.

Layer Responsibility Shared %
Shared Library Models, ViewModels, services, networking, data access 100%
Platform Abstraction DependencyService, interfaces, platform-specific implementations 50 to 80%
Platform Head Native UI, lifecycle hooks, app entry points 0 to 10%

Xamarin.Forms vs. Xamarin.Native

The single most important architectural decision in a Xamarin project is choosing between Xamarin.Forms (now evolved into .NET MAUI) and Xamarin.Native. Both approaches compile to native code; they differ in how you build the UI layer.

Xamarin.Forms

Abstract UI layer with XAML markup. Write once, render natively on each platform. Controls map to native widgets, a Button renders as UIButton on iOS and Android.Widget.Button on Android.

Xamarin.Native

Build separate UI per platform using native APIs (UIKit on iOS, Android SDK). Full control over platform-specific behavior and pixel-perfect layouts.

Criteria Xamarin.Forms Xamarin.Native
UI Code Sharing 90 to 100% shared via XAML 0 to 10%, separate UI per platform
Native API Access Full access via DependencyService Direct access, no abstraction
Custom Renderers Required for platform-specific UI tweaks Not needed, you write native UI directly
Performance Good for most apps; overhead from abstraction layer Maximum, no abstraction overhead
Learning Curve Learn XAML + Forms API Learn each platform’s native UI framework
Best For Line-of-business, data-entry, prototype apps Games, media editors, heavily custom UI

Migration Note: Xamarin.Forms has evolved into .NET MAUI. New projects should start with MAUI. Existing Xamarin.Forms projects can migrate incrementally, the XAML and C# patterns are largely compatible, but the renderer architecture has been replaced by a handler architecture.


Code Sharing Strategies

How you structure shared code determines maintainability, testability, and the speed of adding new features. Xamarin supports two primary strategies, each with distinct trade-offs.

1

Shared Project (SAL)

The Shared Asset Library uses compiler directives (#if __IOS__, #if __ANDROID__) to include platform-specific code within a single project. The IDE compiles the shared code directly into each platform head.

  • Simple to set up, no additional project references
  • Conditional compilation fragments the codebase and reduces readability
  • Best for small prototypes or when platform divergence is minimal

2

.NET Standard / .NET Library

A compiled class library (historically PCL, now .NET Standard 2.0+ or .NET 6+) that both platform heads reference. Platform-specific behavior is injected via interfaces and DependencyService or a DI container.

  • Compile-time type safety across the entire shared layer
  • Clean separation of concerns. Platform code stays in platform projects
  • Recommended for any production app of moderate complexity
Factor Shared Project .NET Standard Library
Code Reuse High (but fragile with directives) High (via interfaces and DI)
Testability Difficult, cannot unit-test shared project directly Full. Library is a standard .NET assembly
Refactoring Safety Low, compiler directives bypass type checks High, compiled with full type checking
NuGet Distribution Not possible Supported, can package as NuGet

UI Development Patterns

Whether you choose Xamarin.Forms or Xamarin.Native, the UI layer benefits from established patterns that separate presentation logic from business logic.

MVVM (Model-View-ViewModel)

The dominant pattern in Xamarin. Views (XAML or native) bind to ViewModel properties via INotifyPropertyChanged. Commands handle user actions. The ViewModel has no knowledge of the View, enabling unit testing without a UI.

Data Binding

Xamarin.Forms provides built-in data binding between XAML elements and ViewModel properties. One-way, two-way, and one-way-to-source modes control data flow. Compiled bindings catch errors at build time.

DependencyService / DI

Register platform-specific implementations against shared interfaces. The runtime resolves the correct implementation for the current platform. For production apps, prefer a full DI container (Autofac, DryIoc, Microsoft.Extensions.DependencyInjection) over the built-in DependencyService.

Custom Renderers / Handlers

When Xamarin.Forms controls need platform-specific appearance or behavior, custom renderers subclass the native control. In MAUI, handlers replace renderers with a lighter-weight pattern that maps cross-platform properties to native views.

Performance Tip: Use compiled bindings (x:DataType in XAML) instead of reflection-based bindings. Compiled bindings resolve at build time, eliminate runtime type lookups, and surface binding errors in the compiler output rather than at runtime.


Testing Xamarin Applications

A testable architecture is one of Xamarin’s strongest advantages over native development. The shared .NET Standard library is a standard .NET assembly. You can test it with the same tools and frameworks you use for any .NET project.

1

Unit Testing

Test ViewModels, services, and business logic with xUnit, NUnit, or MSTest. Because the shared layer has no platform dependencies, tests run on any .NET runtime, no emulator or device required.

  • Target the shared library project directly
  • Mock platform dependencies with Moq or NSubstitute
  • Aim for 80%+ coverage on the shared layer

2

Integration Testing

Verify that platform-specific implementations work correctly with the shared layer. Run tests on real devices or emulators using the platform test runner.

  • Use xUnit runner for iOS and Android
  • Test DependencyService resolution and platform API calls
  • Validate SQLite, file system, and network operations on-device

3

UI Testing

Automated UI tests simulate user interactions across the app. Xamarin.UITest (now open-source) integrates with App Center and local test runners.

  • Write tests in C# using the UITest framework
  • Query elements by automation ID, class, or marked text
  • Run on cloud device farms (App Center Test, Firebase Test Lab)
Test Type Scope Runs On Speed
Unit ViewModels, services, models Desktop / CI Fast (ms)
Integration Platform implementations, DI resolution Device / Emulator Medium (seconds)
UI / E2E Full user flows, navigation, rendering Device / Cloud Slow (minutes)

Build and Deployment

Shipping a Xamarin app involves platform-specific build pipelines, signing requirements, and store submission processes. The shared codebase means you build once and package for each target.

CI/CD Pipeline

Use Azure DevOps, GitHub Actions, or App Center to automate builds. Each pipeline runs MSBuild for the shared library and platform heads, runs unit tests, and produces signed packages.

iOS Signing

Requires an Apple Developer account, provisioning profile, and distribution certificate. The IPA is built on macOS with Xcode installed. Fastlane automates certificate management and screenshot capture.

Android Signing

Sign the APK/AAB with a keystore. Google Play requires AAB format. Upload the signing key to Google Play App Signing for managed key rotation. The Android SDK and JDK must match the project’s target framework.

Store Submission

App Store Connect (iOS) and Google Play Console (Android) each require metadata, screenshots, privacy URLs, and review compliance. Plan for 1 to 3 day review cycles on iOS and 1 to 7 days on Android.

Build Size Note: Xamarin apps include the Mono runtime, which adds approximately 3 to 5 MB to the final package size. Linker settings (SDK assemblies only vs. all assemblies) significantly affect output size. Use the linker in release builds and enable AOT + LLVM on iOS for smallest binaries.


Xamarin to .NET MAUI Migration Path

Microsoft has officially superseded Xamarin with .NET MAUI (Multi-platform App UI). Understanding the migration path is critical for teams maintaining existing Xamarin apps or planning new cross-platform investments.

1

Assess Current State

Audit your Xamarin.Forms version, custom renderer count, and platform-specific code volume. Apps with few custom renderers and standard controls migrate most smoothly. Heavy native interop requires more effort.

2

Update to Latest Xamarin.Forms

Upgrade to Xamarin.Forms 5.0 before migrating. This version is closest to MAUI’s API surface and introduces compatibility shims. Fix any deprecation warnings at this stage.

3

Convert Renderers to Handlers

MAUI replaces custom renderers with a handler pattern. Each handler maps a single cross-platform property to a native view change, no subclassing the entire native control. This is the most labor-intensive migration step.

4

Adopt the Single Project Model

MAUI uses a single project with platform-specific folders instead of separate head projects. Move platform code into Platforms/iOS, Platforms/Android, and Platforms/Windows directories.

Concept Xamarin.Forms .NET MAUI
Project Structure Separate head projects per platform Single project with platform folders
UI Customization Custom Renderers Handlers
Target Framework Mono / .NET Standard 2.0 .NET 6+ (single BCL)
Layout Engine Xamarin.Forms layout system Same core, optimized rendering
Hot Reload XAML Hot Reload (limited) Full Hot Reload (XAML + C#)

Next Steps

Whether you are starting fresh, maintaining an existing Xamarin app, or planning a migration to MAUI, the following actions will set you on the right path.

1

New Projects: Start with .NET MAUI

Do not start new projects on Xamarin.Forms. Use .NET MAUI for the single-project model, handler architecture, and ongoing Microsoft support. The XAML and MVVM patterns transfer directly.

2

Existing Xamarin Apps: Audit and Plan

Inventory your custom renderers, platform-specific code, and third-party library dependencies. Create a migration timeline aligned with your release cadence. Prioritize renderer-to-handler conversion.

3

Invest in Shared Logic

Move as much code as possible into .NET Standard / .NET libraries with clean interfaces. The more logic lives in shared, testable assemblies, the easier both maintenance and migration become.

4

Automate Your Pipeline

Set up CI/CD with Azure DevOps or GitHub Actions. Automate builds, unit tests, and distribution to internal testers. Manual builds are the enemy of shipping velocity.

Bottom Line: Xamarin proved that C# developers can build truly native mobile apps without sacrificing performance or API access. .NET MAUI continues that mission with a modernized architecture. The investment you make in shared code, MVVM patterns, and testable architecture pays dividends whether you stay on Xamarin or migrate forward.

Dev Station works with teams across the United States and the United Kingdom. Application data is held to SOC 2 or HIPAA where a US client requires it, and to GDPR with ISO 27001 for UK and EU records. Our engineers work from Vietnam with overlap into US Eastern, US Pacific and UK GMT hours, and we invoice in USD or GBP.

Ask an AI about this

Want an AI assistant to summarize or cite this guide?

Click any link below to open the AI with a pre-filled prompt referencing this article:

Ready to Build Your Field App?

Contact Dev Station Technology to discuss your project requirements and receive a development roadmap within 48 hours.

Get a Quote →

Related articles

Let's Talk