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.
Overview
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
Section 1
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–80% |
| Platform Head | Native UI, lifecycle hooks, app entry points | 0–10% |
Section 2
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
| Criteria | Xamarin.Forms | Xamarin.Native |
|---|---|---|
| UI Code Sharing | 90–100% shared via XAML | 0–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.
Section 3
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 |
Section 4
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
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.
Section 5
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) |
Section 6
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–3 day review cycles on iOS and 1–7 days on Android.
Build Size Note: Xamarin apps include the Mono runtime, which adds approximately 3–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.
Section 7
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#) |
Action
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.
Serving Clients Across the US & UK
Dev Station Technology partners with startups, enterprises, and development teams throughout the United States and the United Kingdom. Our Vietnam-based engineering teams offer significant time-zone overlap with both US Eastern/Pacific and UK GMT business hours, ensuring real-time collaboration and faster delivery cycles. We bill in USD and GBP, comply with US regulations (SOC 2, HIPAA) and UK/EU standards (GDPR, ISO 27001), and provide dedicated account management for North American and British clients.
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
Contents
Subscribe To Our Newsletter


