Por Que Migrar do Xamarin.Forms para o .NET MAUI É Urgente em 2026
Vou ser direto: se ainda tem uma aplicação em Xamarin.Forms em produção, a situação é complicada. O suporte da Microsoft terminou em 1 de maio de 2024. Isso significa zero correções de segurança, zero atualizações de compatibilidade e — pior — incompatibilidade crescente com os SDKs mais recentes do Android e iOS. Em 2026, já não estamos a falar de simples dívida técnica. Estamos a falar de aplicações que literalmente não conseguem ser publicadas nas lojas.
O Google agora exige que as apps visem pelo menos o Android 14 (API nível 34+) para publicar atualizações na Play Store, mas o Xamarin suporta apenas até o Android 13. Do lado da Apple, a exigência é o iOS 17, e o Xamarin ficou pelo iOS 16. Resultado? A sua app fica bloqueada — sem possibilidade de atualização.
Neste guia, vamos percorrer todo o processo de migração passo a passo. Com exemplos de código reais, soluções para os problemas mais comuns e estratégias que já vi funcionar em projetos reais. Quer esteja a usar o .NET Upgrade Assistant ou a fazer tudo manualmente, está tudo coberto aqui.
Diferenças Fundamentais entre Xamarin.Forms e .NET MAUI
Antes de mergulhar na migração, vale a pena entender as diferenças arquiteturais entre as duas plataformas. E não, não se trata apenas de mudar namespaces — a filosofia inteira do projeto mudou.
Estrutura de Projeto Unificada
No Xamarin.Forms, tínhamos projetos separados para cada plataforma: um projeto .Android, um .iOS, um .UWP, e um projeto partilhado ou .NET Standard. Era uma confusão de solution files.
No .NET MAUI, tudo está consolidado num projeto único com uma pasta Platforms/ que contém o código específico de cada plataforma. Muito mais limpo.
// Estrutura Xamarin.Forms (antiga)
MeuApp/
├── MeuApp/ (projeto partilhado)
├── MeuApp.Android/ (projeto Android)
├── MeuApp.iOS/ (projeto iOS)
└── MeuApp.UWP/ (projeto UWP)
// Estrutura .NET MAUI (nova)
MeuApp/
├── Platforms/
│ ├── Android/
│ ├── iOS/
│ ├── MacCatalyst/
│ └── Windows/
├── Resources/
├── Views/
├── ViewModels/
├── Services/
└── MauiProgram.cs
Renderers vs. Handlers
Esta é, honestamente, a mudança arquitetural mais impactante. No Xamarin.Forms, os Custom Renderers criavam um elemento pai extra na árvore visual (por exemplo, um ViewGroup no Android). No .NET MAUI, os Handlers são desacoplados dos controlos multiplataforma, o que elimina essa camada extra. Menos memória, arranques mais rápidos.
Ponto de Entrada da Aplicação
O Xamarin.Forms usava App.xaml.cs com LoadApplication(). O .NET MAUI trocou isso pelo MauiProgram.cs, seguindo o padrão de builder que já conhecemos do ASP.NET Core:
// Xamarin.Forms (antigo)
public class MainActivity : FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
}
// .NET MAUI (novo)
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
return builder.Build();
}
}
Namespaces Atualizados
Todos os namespaces mudaram. Aqui fica um mapeamento rápido das substituições mais comuns (guarde isto — vai precisar):
// Mapeamento de Namespaces
Xamarin.Forms → Microsoft.Maui.Controls
Xamarin.Forms.Xaml → Microsoft.Maui.Controls.Xaml
Xamarin.Essentials → Microsoft.Maui.ApplicationModel (e sub-namespaces)
Xamarin.Forms.Maps → Microsoft.Maui.Controls.Maps
Xamarin.Forms.Shapes → Microsoft.Maui.Controls.Shapes
Xamarin.CommunityToolkit → CommunityToolkit.Maui
Nos ficheiros XAML, a declaração do namespace raiz também muda:
<!-- Xamarin.Forms -->
xmlns="http://xamarin.com/schemas/2014/forms"
<!-- .NET MAUI -->
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
Checklist de Preparação Antes de Migrar
Uma migração bem-sucedida começa muito antes de tocar no código. Já vi projetos falharem por pular esta fase, por isso levem isto a sério:
- Atualize para Xamarin.Forms 5.0: O .NET Upgrade Assistant funciona melhor com projetos que usam Xamarin.Forms 5.0 e .NET Standard 2.0 ou superior. Se ainda está numa versão anterior, atualize primeiro — não tente saltar passos.
- Faça um backup completo: Use Git para criar um branch dedicado à migração. Nunca migre na branch principal. Parece óbvio, mas já vi acontecer.
- Audite os pacotes NuGet: Faça um inventário completo de todas as dependências. Verifique quais têm versões compatíveis com .NET 8/9/10 e quais precisam de substituição. Esta parte costuma demorar mais do que se espera.
- Identifique Custom Renderers: Liste todos os renderers personalizados. Estes vão precisar de ser reescritos como handlers — priorize os mais críticos para o funcionamento da app.
- Estabeleça benchmarks de performance: Meça tempos de arranque, consumo de memória e responsividade da UI antes da migração. Sem estes números, não há como comparar depois.
- Verifique código específico de plataforma: Revise o uso de
DependencyService, efeitos e código nativo que poderá precisar de ajustes. - Atualize o ambiente de desenvolvimento: Instale o Visual Studio 2026 (ou 2022 v17.14+) com o workload .NET MAUI e o .NET 10 SDK.
Migração com o .NET Upgrade Assistant
A ferramenta oficial da Microsoft para automatizar parte do processo é o .NET Upgrade Assistant. Está disponível como extensão do Visual Studio e como ferramenta CLI. Na minha experiência, funciona bem para uns 60-70% do trabalho — o resto é manual.
Instalação via CLI
dotnet tool install -g upgrade-assistant
Executar a Migração
# Navegar até à pasta do projeto Xamarin.Forms
cd /caminho/para/MeuApp
# Executar o Upgrade Assistant
upgrade-assistant upgrade MeuApp.csproj
A ferramenta oferece dois modos:
- In-place: Atualiza o projeto original diretamente. Mais rápido, mas arriscado.
- Side-by-side: Cria um novo projeto MAUI ao lado do original, mantendo o Xamarin intacto. Este é o que eu recomendo para projetos complexos.
O Que o Upgrade Assistant Faz Automaticamente
- Converte o ficheiro
.csprojpara o formato SDK do .NET - Atualiza os Target Framework Monikers (TFMs)
- Substitui namespaces do
Xamarin.FormsporMicrosoft.Maui - Remove referências ao
Xamarin.Essentials - Atualiza versões do SkiaSharp para compatibilidade com MAUI
- Faz substituições básicas em ficheiros XAML
O Que Precisa de Fazer Manualmente
O Upgrade Assistant não resolve tudo. Longe disso. Após executá-lo, prepare-se para:
- Corrigir erros de compilação restantes (referências ambíguas, dependências em falta)
- Migrar Custom Renderers para Handlers
- Atualizar pacotes NuGet incompatíveis
- Ajustar código específico de plataforma na nova estrutura
Platforms/ - Testar exaustivamente em todas as plataformas-alvo
Limitações do Upgrade Assistant
A ferramenta não suporta migração de projetos UWP, projetos de extensão iOS ou projetos de binding. O projeto Xamarin.Forms deve usar pelo menos a versão 4.8, mas para melhores resultados, use a 5.0 com .NET Standard 2.0+.
Migração Manual Passo a Passo
Para projetos grandes e complexos, a migração manual dá mais controlo sobre o processo. É mais trabalhoso? Sim. Mas também evita surpresas desagradáveis. Vamos ao passo a passo:
Passo 1: Criar o Projeto .NET MAUI
dotnet new maui -n MeuApp.Maui
cd MeuApp.Maui
Passo 2: Atualizar o Ficheiro .csproj
Configure os TFMs para as plataformas que pretende suportar:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net10.0-android;net10.0-ios;net10.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">
$(TargetFrameworks);net10.0-windows10.0.19041.0
</TargetFrameworks>
<OutputType>Exe</OutputType>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<ApplicationTitle>MeuApp</ApplicationTitle>
<ApplicationId>com.empresa.meuapp</ApplicationId>
</PropertyGroup>
</Project>
Passo 3: Migrar ViewModels e Lógica de Negócio
A boa notícia: os ViewModels e a lógica de negócio geralmente migram com pouquíssimas alterações. Se estiver a usar MVVM corretamente, a maior parte do código C# funciona quase diretamente. A principal mudança é mesmo nos namespaces:
// Antes (Xamarin.Forms)
using Xamarin.Forms;
using Xamarin.Essentials;
public class MeuViewModel : BindableObject
{
public ICommand CarregarCommand { get; }
public MeuViewModel()
{
CarregarCommand = new Command(async () => await CarregarDados());
}
private async Task CarregarDados()
{
var localizacao = await Geolocation.GetLocationAsync();
}
}
// Depois (.NET MAUI)
using Microsoft.Maui.Controls;
using Microsoft.Maui.Devices.Sensors;
public class MeuViewModel : BindableObject
{
public ICommand CarregarCommand { get; }
public MeuViewModel()
{
CarregarCommand = new Command(async () => await CarregarDados());
}
private async Task CarregarDados()
{
var localizacao = await Geolocation.GetLocationAsync(
new GeolocationRequest(GeolocationAccuracy.Medium));
}
}
Passo 4: Migrar Páginas XAML
As páginas XAML precisam de atualização dos namespaces e, em alguns casos, ajustes nos layouts. Veja este exemplo de conversão:
<!-- Antes (Xamarin.Forms) -->
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MeuApp.Views.PaginaPrincipal">
<StackLayout Padding="20">
<Label Text="Bem-vindo"
FontSize="24"
HorizontalOptions="CenterAndExpand" />
<Frame CornerRadius="10" HasShadow="True">
<Label Text="Conteúdo aqui" />
</Frame>
</StackLayout>
</ContentPage>
<!-- Depois (.NET MAUI) -->
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MeuApp.Views.PaginaPrincipal">
<VerticalStackLayout Padding="20" Spacing="16">
<Label Text="Bem-vindo"
FontSize="24"
HorizontalOptions="Center" />
<Border StrokeShape="RoundRectangle 10">
<Shadow Brush="Black" Opacity="0.3" />
<Label Text="Conteúdo aqui" />
</Border>
</VerticalStackLayout>
</ContentPage>
Algumas notas importantes aqui: o StackLayout ainda funciona no MAUI, mas os novos VerticalStackLayout e HorizontalStackLayout têm melhor performance por serem mais simples internamente. O Frame foi substituído pelo Border, que é mais flexível. E CenterAndExpand? Simplificou para apenas Center — sinceramente, já devia ter sido assim desde o início.
Migrando Custom Renderers para Handlers
Ok, esta é a parte que mais assusta — e com razão. A arquitetura é fundamentalmente diferente. Mas, acreditem, o resultado compensa: handlers são mais rápidos, mais limpos e muito mais fáceis de manter a longo prazo.
Abordagem Gradual: Compatibilidade Temporária
A boa notícia é que o .NET MAUI permite reutilizar renderers existentes temporariamente enquanto se converte para handlers um a um. Isto faz-se registando o renderer no MauiProgram.cs:
builder
.UseMauiApp<App>()
.ConfigureMauiHandlers(handlers =>
{
#if ANDROID
handlers.AddHandler(typeof(MeuControloPersonalizado),
typeof(MeuRendererAndroid));
#elif IOS
handlers.AddHandler(typeof(MeuControloPersonalizado),
typeof(MeuRendererIOS));
#endif
});
Mas atenção: esta abordagem é temporária. A Microsoft não garante compatibilidade de renderers em versões futuras. O ideal é ir convertendo tudo progressivamente.
Exemplo Completo: Converter um Renderer para Handler
Vamos ver como converter um Entry personalizado com fundo arredondado. Pode parecer muito código, mas cada parte é bastante direta.
1. Definir a interface:
public interface IEntryArredondado : IView
{
string Text { get; }
Color CorFundo { get; }
float RaioBorda { get; }
}
2. Criar o controlo multiplataforma:
public class EntryArredondado : View, IEntryArredondado
{
public static readonly BindableProperty TextProperty =
BindableProperty.Create(nameof(Text), typeof(string), typeof(EntryArredondado));
public static readonly BindableProperty CorFundoProperty =
BindableProperty.Create(nameof(CorFundo), typeof(Color), typeof(EntryArredondado));
public static readonly BindableProperty RaioBordaProperty =
BindableProperty.Create(nameof(RaioBorda), typeof(float), typeof(EntryArredondado), 12f);
public string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public Color CorFundo
{
get => (Color)GetValue(CorFundoProperty);
set => SetValue(CorFundoProperty, value);
}
public float RaioBorda
{
get => (float)GetValue(RaioBordaProperty);
set => SetValue(RaioBordaProperty, value);
}
}
3. Criar o handler para Android (na pasta Platforms/Android/):
using Android.Graphics.Drawables;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform;
using AndroidX.AppCompat.Widget;
public partial class EntryArredondadoHandler : ViewHandler<IEntryArredondado, AppCompatEditText>
{
public static IPropertyMapper<IEntryArredondado, EntryArredondadoHandler> PropertyMapper =
new PropertyMapper<IEntryArredondado, EntryArredondadoHandler>(ViewHandler.ViewMapper)
{
[nameof(IEntryArredondado.Text)] = MapText,
[nameof(IEntryArredondado.CorFundo)] = MapCorFundo,
[nameof(IEntryArredondado.RaioBorda)] = MapRaioBorda
};
public EntryArredondadoHandler() : base(PropertyMapper) { }
protected override AppCompatEditText CreatePlatformView()
{
return new AppCompatEditText(Context);
}
private static void MapText(EntryArredondadoHandler handler, IEntryArredondado entry)
{
handler.PlatformView.Text = entry.Text;
}
private static void MapCorFundo(EntryArredondadoHandler handler, IEntryArredondado entry)
{
AplicarEstilo(handler, entry);
}
private static void MapRaioBorda(EntryArredondadoHandler handler, IEntryArredondado entry)
{
AplicarEstilo(handler, entry);
}
private static void AplicarEstilo(EntryArredondadoHandler handler, IEntryArredondado entry)
{
var drawable = new GradientDrawable();
drawable.SetCornerRadius(entry.RaioBorda * handler.PlatformView.Context.Resources.DisplayMetrics.Density);
drawable.SetColor(entry.CorFundo.ToPlatform(Colors.White));
handler.PlatformView.Background = drawable;
}
}
4. Registar o handler:
builder
.UseMauiApp<App>()
.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler<EntryArredondado, EntryArredondadoHandler>();
});
A grande diferença em relação aos renderers? Cada propriedade tem o seu próprio método de mapeamento no PropertyMapper, em vez de depender de um único OnElementPropertyChanged. Isto torna o código mais organizado e, sobretudo, muito mais fácil de depurar quando algo corre mal.
Atualização de Pacotes NuGet e Dependências
Ah, os pacotes NuGet. Esta é provavelmente a área mais frustrante de toda a migração. Vamos ver como lidar com isto de forma sistemática.
Regra Geral de Compatibilidade
Pacotes Xamarin.Forms não são compatíveis com .NET 8+ a menos que tenham sido recompilados com TFMs do .NET. A exceção (e uma exceção bem-vinda) são pacotes Android que visam os frameworks monoandroid e monoandroidXX.X, que ainda funcionam.
Mapeamento de Pacotes Comuns
Eis as substituições que vão cobrir a maioria dos casos:
// Substituições Directas
Xamarin.Forms → Microsoft.Maui.Controls (incluído no SDK)
Xamarin.Essentials → Microsoft.Maui.Essentials (incluído no SDK)
Xamarin.CommunityToolkit → CommunityToolkit.Maui
Xamarin.CommunityToolkit.Markup → CommunityToolkit.Maui.Markup
SkiaSharp.Views.Forms → SkiaSharp.Views.Maui.Controls
Newtonsoft.Json → System.Text.Json (recomendado) ou manter Newtonsoft
SQLite-net-pcl → sqlite-net-pcl (compatível — manter)
FFImageLoading → FFImageLoading.Maui (versão community)
// UI Components de Terceiros
Telerik UI for Xamarin → Telerik UI for .NET MAUI
DevExpress Xamarin → DevExpress .NET MAUI
Syncfusion Xamarin.Forms → Syncfusion .NET MAUI
Verificar Pacotes Desatualizados
# Listar todos os pacotes desatualizados
dotnet list package --outdated
# Restaurar com auditoria de segurança
dotnet restore --audit
Se não encontrar uma versão compatível de algum pacote, as opções são: recompilar o pacote com os TFMs do .NET (se tiver acesso ao código-fonte), procurar uma versão preview, ou encontrar uma alternativa. Não há atalhos aqui, infelizmente.
Migrando Xamarin.Essentials e o DependencyService
O Xamarin.Essentials foi integrado diretamente no .NET MAUI — já não é um pacote separado, o que simplifica bastante as coisas. As APIs ficaram distribuídas por novos namespaces:
// Mapeamento de APIs do Xamarin.Essentials
Xamarin.Essentials.Geolocation → Microsoft.Maui.Devices.Sensors.Geolocation
Xamarin.Essentials.SecureStorage → Microsoft.Maui.Storage.SecureStorage
Xamarin.Essentials.Preferences → Microsoft.Maui.Storage.Preferences
Xamarin.Essentials.Connectivity → Microsoft.Maui.Networking.Connectivity
Xamarin.Essentials.Battery → Microsoft.Maui.Devices.Battery
Xamarin.Essentials.DeviceInfo → Microsoft.Maui.Devices.DeviceInfo
Xamarin.Essentials.Share → Microsoft.Maui.ApplicationModel.DataTransfer.Share
Xamarin.Essentials.Clipboard → Microsoft.Maui.ApplicationModel.DataTransfer.Clipboard
Substituir o DependencyService
O DependencyService do Xamarin.Forms dá lugar à injeção de dependências nativa do .NET MAUI, baseada no Microsoft.Extensions.DependencyInjection. Se já trabalhou com ASP.NET Core, vai sentir-se em casa:
// Antes (Xamarin.Forms) — registo com atributo
[assembly: Dependency(typeof(ServicoNotificacao))]
public class ServicoNotificacao : IServicoNotificacao
{
public void MostrarNotificacao(string titulo, string mensagem)
{
// implementação Android
}
}
// Uso
var servico = DependencyService.Get<IServicoNotificacao>();
servico.MostrarNotificacao("Olá", "Mundo");
// Depois (.NET MAUI) — registo no MauiProgram.cs
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder.UseMauiApp<App>();
#if ANDROID
builder.Services.AddSingleton<IServicoNotificacao, Platforms.Android.ServicoNotificacao>();
#elif IOS
builder.Services.AddSingleton<IServicoNotificacao, Platforms.iOS.ServicoNotificacao>();
#endif
return builder.Build();
}
// Uso (via injeção de construtor)
public class MeuViewModel
{
private readonly IServicoNotificacao _servico;
public MeuViewModel(IServicoNotificacao servico)
{
_servico = servico;
}
}
A mudança para injeção de construtor é, na minha opinião, uma das melhores melhorias. O código fica muito mais testável e previsível.
Migrar o CommunityToolkit
O Xamarin.CommunityToolkit foi substituído pelo CommunityToolkit.Maui. A instalação é direta:
dotnet add package CommunityToolkit.Maui
E no MauiProgram.cs:
builder
.UseMauiApp<App>()
.UseMauiCommunityToolkit();
Migração com o AWS Transform (Alternativa Automatizada)
Em 2026, surgiu uma alternativa interessante: o AWS Transform. Esta ferramenta da Amazon consegue transformar aplicações Xamarin.Forms com UI complexa, navegação e código específico de plataforma para .NET MAUI no .NET 10.
O AWS Transform vai além do .NET Upgrade Assistant — lida com migrações de código específico de plataforma (renderers iOS e Android para handlers), atualizações de padrões de navegação, injeção de dependências e implementação da estrutura de projeto único. Para projetos muito grandes, pode ser uma opção a considerar seriamente.
Testes e Validação Pós-Migração
A migração não está completa até testar tudo. E quando digo tudo, é mesmo tudo. Eis a estratégia que recomendo:
1. Testes de Compilação
Configure o projeto para tratar avisos como erros durante a validação:
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
Isto garante que não se ignoram APIs obsoletas que podem causar falhas em runtime. Vale o incómodo, confiem.
2. Testes em Dispositivos Físicos
Nunca confiem apenas em emuladores. Testem em dispositivos físicos Android e iOS. Prestem especial atenção a:
- Tempos de arranque da aplicação
- Fluidez da navegação e scrolling
- Consumo de memória durante uso prolongado
- Funcionamento de APIs nativas (câmara, GPS, notificações)
- Comportamento offline e gestão de estado
3. Comparar com os Benchmarks Pré-Migração
Lembram-se dos benchmarks que estabeleceram antes? É agora que são úteis. Tipicamente, após uma migração bem-sucedida, podem esperar:
- Lançamentos até 40% mais rápidos
- Tamanho dos pacotes até 25% menores
- Menor consumo de memória graças à arquitetura de handlers
Se os números não melhoraram (ou pioraram), algo pode não estar bem na migração — vale investigar.
4. Testes de Regressão
Executem toda a suite de testes unitários e de integração. Se estavam a usar xUnit com Xamarin.Forms, a boa notícia é que os testes de lógica de negócio e ViewModels devem funcionar com ajustes mínimos — basicamente os mesmos namespaces de sempre.
Erros Comuns e Como Evitá-los
Depois de acompanhar várias migrações, estes são os erros que vejo com mais frequência:
- Ignorar avisos de compilação: O build pode ter sucesso, mas APIs obsoletas vão causar falhas em runtime. Usem
TreatWarningsAsErrors— a sério. - Manter renderers permanentemente: A camada de compatibilidade é temporária. Renderers legados podem causar fugas de memória em versões mais recentes do OS.
- Migrar tudo de uma vez: Resistam à tentação. Uma abordagem incremental, módulo a módulo, é muito mais segura. Testem cada parte antes de avançar.
- Esquecer a pasta Platforms/: O código específico de plataforma tem de estar organizado na nova estrutura de pastas do MAUI. Parece trivial, mas causa muita confusão.
- Não atualizar pipelines CI/CD: Os pipelines Xamarin são frequentemente incompatíveis com agentes de build modernos. Transicionem para GitHub Actions ou Azure DevOps adaptados ao .NET 10.
Perguntas Frequentes
Quanto tempo demora a migração do Xamarin.Forms para o .NET MAUI?
Depende muito da complexidade. Apps simples podem ficar prontas em 1 a 2 dias. Apps empresariais com código legado extenso, muitos custom renderers e dependências de terceiros? Podem facilmente levar de 4 a 8 semanas. Ferramentas como o .NET Upgrade Assistant ou o AWS Transform ajudam a reduzir esse tempo em cerca de 50%, mas não fazem magia.
É possível reutilizar o código Xamarin.Forms existente no .NET MAUI?
Sim, especialmente a lógica de negócio, serviços e ViewModels — estes geralmente migram com poucas alterações além dos namespaces. O código XAML precisa de ajustes nos namespaces e, por vezes, nos layouts. Os Custom Renderers precisam de ser convertidos para handlers para máxima performance, mas podem funcionar temporariamente via compatibilidade.
O .NET MAUI está pronto para aplicações empresariais em produção?
Sim, sem dúvida. Com o .NET 10 (LTS, com suporte até novembro de 2028), o .NET MAUI está estável e é usado em produção por grandes empresas. A Microsoft continua a investir no framework, com melhorias regulares de performance e correções de estabilidade.
Posso publicar a aplicação MAUI sobre a aplicação Xamarin existente nas lojas?
Sim, desde que mantenha o mesmo ApplicationId (nome do pacote) e a mesma identidade de assinatura. A app MAUI substitui a Xamarin nas lojas sem precisar de criar uma nova listagem. Os utilizadores recebem a atualização normalmente — nem vão notar a diferença.
E se não migrar — o que acontece?
As consequências são sérias. Em 2026, tanto a Google Play como a App Store rejeitam atualizações de apps que não visem versões recentes do Android e iOS. O Xamarin não suporta Android 14+ nem iOS 17+, o que significa que a sua app fica presa — sem possibilidade de publicar atualizações ou correções de segurança. Não é uma questão de "se", é de "quando" vai ser um problema.