Guia Completo: Top 10 + 10 Flutter Favorite Packages (Edição 2025)
1. Riverpod
O Riverpod é a evolução do Provider, oferecendo um gerenciamento de estado robusto, reativo e totalmente independente do BuildContext. Ele elimina erros em tempo de execução ao capturar problemas de estado durante a compilação.
Exemplo Completo:
// Provedor de estado global
final greetingProvider = Provider((ref) => "Bem-vindo ao Flutter 2025!");
class MyHome extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
// Escuta o provedor de forma reativa e segura
final message = ref.watch(greetingProvider);
return Scaffold(body: Center(child: Text(message)));
}
}
2. Dio
O Dio é o cliente HTTP favorito para projetos profissionais que exigem controle avançado, como interceptadores de segurança, cancelamento de requisições e acompanhamento de progresso.
Exemplo Completo:
final dio = Dio();
Future<void> fetchData() async {
try {
final response = await dio.get('https://api.exemplo.com/v1/dados');
print(response.data);
} on DioException catch (e) {
print('Erro na chamada: ${e.response?.statusCode}'); // Trata erros específicos de rede
}
}
3. Mcp_server
Este pacote implementa o Model Context Protocol, permitindo que o seu app se comunique com IDEs Agênticos como o Antigravity. Ele permite que agentes de IA validem seu código e executem testes de forma autônoma.
Exemplo Completo:
import 'package:mcp_server/mcp_server.dart';
void main() async {
final server = McpServer(
name: "FlutterDevAgent",
capabilities: [DartAnalysisCapability(), TestCapability()],
);
await server.start(); // Prepara o ambiente para interação com agentes de IA
}
4. Go Router
O pacote oficial de navegação declarativa mantido pela equipe do Flutter. Ele simplifica o gerenciamento de rotas complexas e é essencial para o suporte nativo a Deep Linking.
Exemplo Completo:
final _router = GoRouter(
routes: [
GoRoute(
path: '/carro/:modelo',
builder: (context, state) => CarDetailScreen(
modelo: state.pathParameters['modelo']!, // Captura parâmetros da URL
),
),
],
);
5. Drift
O Drift é o motor SQL reativo favorito para persistência local. Ele transforma tabelas SQL em classes Dart com segurança de tipos, atualizando a UI automaticamente quando os dados mudam.
Exemplo Completo:
class Items extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get title => text()();
}
// Consultas reativas que notificam a UI
Stream<List<Item>> watchItems(Database db) => db.select(db.items).watch();
6. Flutter Secure Storage
Indispensável para segurança, este pacote armazena credenciais e tokens JWT de forma criptografada usando as camadas nativas Keychain (iOS) e Keystore (Android).
Exemplo Completo:
final storage = FlutterSecureStorage(); // Gravação segura de tokens await storage.write(key: 'auth_token', value: 'secret_jwt_123'); // Leitura protegida String? token = await storage.read(key: 'auth_token');
7. Freezed
Um gerador de código para classes de dados imutáveis. Ele elimina o código repetitivo (boilerplate) e garante que seus modelos de dados sejam seguros e previsíveis.
Exemplo Completo:
@freezed
class User with _$User {
const factory User({required String name, required int age}) = _User;
// Gera automaticamente métodos para JSON
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}
8. Isar
O banco de dados NoSQL ultrarrápido preferido para Flutter. É ideal para aplicações que precisam processar grandes volumes de dados locais com latência mínima.
Exemplo Completo:
@collection
class Carro {
Id id = Isar.autoIncrement;
late String marca;
}
// Busca rápida usando filtros nativos
final results = await isar.carros.filter().marcaEqualTo("Ford").findAll();
9. Lottie
Permite renderizar animações profissionais de alta fidelidade sem comprometer o desempenho do app, utilizando arquivos JSON leves exportados do Adobe After Effects.
Exemplo Completo:
// Exibe uma animação de sucesso instantaneamente
Lottie.asset('assets/animations/success.json', repeat: false);
10. Intl
A biblioteca base para localização e internacionalização. Ela garante que o app possa ser traduzido e formate moedas e datas conforme a região do usuário.
Exemplo Completo:
// Formatação para Real Brasileiro String preco = NumberFormat.simpleCurrency(locale: 'pt_BR').format(1200.50); // Resultado: R$ 1.200,50
11. Provider
Apesar da ascensão do Riverpod, o Provider continua sendo um dos favoritos oficiais para injeção de dependência e gerenciamento de estado simples. Ele é a base sobre a qual muitos desenvolvedores aprendem a gerenciar a árvore de widgets.
Exemplo Completo:
// Definindo um modelo simples
class MyData extends ChangeNotifier {
int value = 0;
void increment() {
value++;
notifyListeners();
}
}
// No Widget
Consumer<MyData>(
builder: (context, data, child) => Text('${data.value}'),
);
12. Cached Network Image
Indispensável para qualquer app que consome imagens da web. Ele baixa, armazena em cache e exibe imagens, economizando o plano de dados do usuário e melhorando a performance de scroll.
Exemplo Completo:
CachedNetworkImage( imageUrl: "https://exemplo.com/carro.jpg", placeholder: (context, url) => CircularProgressIndicator(), errorWidget: (context, url, error) => Icon(Icons.error), );
13. Url Launcher
O pacote favorito para interagir com outros apps do sistema. Permite abrir links no navegador, enviar e-mails, fazer chamadas telefônicas ou enviar SMS.
Exemplo Completo:
final Uri _url = Uri.parse('https://flutter.dev');
Future<void> _launchUrl() async {
if (!await launchUrl(_url)) {
throw Exception('Não foi possível abrir $_url');
}
}
14. Path Provider
Essencial para manipulação de arquivos. Ele localiza os diretórios corretos no sistema de arquivos do iOS e Android (como as pastas de Documentos ou Cache) de forma agnóstica à plataforma.
Exemplo Completo:
final directory = await getApplicationDocumentsDirectory();
final file = File('${directory.path}/meu_arquivo.txt');
await file.writeAsString('Dados salvos localmente');
15. Shared Preferences
Diferente do Drift ou Isar, este é focado em dados pequenos e simples (chave-valor), como as configurações de tema (Dark/Light) ou se o usuário já viu o tutorial de boas-vindas.
Exemplo Completo:
final SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setBool('repeat', true); // Salva preferência
final bool? repeat = prefs.getBool('repeat'); // Lê preferência
16. Google Fonts
Permite usar centenas de fontes do Google Fonts dinamicamente, sem precisar baixar os arquivos .ttf e declará-los manualmente no pubspec.yaml.
Exemplo Completo:
Text( 'Estilizando com Google Fonts', style: GoogleFonts.lato(fontSize: 20, fontWeight: FontWeight.bold), );
17. Video Player
O pacote oficial para reprodução de vídeo. Oferece controle total sobre o buffer, reprodução, pausa e volume para vídeos locais ou via streaming.
Exemplo Completo:
_controller = VideoPlayerController.networkUrl(Uri.parse('https://video.com/movie.mp4'))
..initialize().then((_) {
setState(() {}); // Atualiza UI após carregar primeiro frame
});
18. Sign In With Apple
Fundamental para conformidade com a App Store. Ele simplifica a autenticação usando a conta da Apple, lidando com os fluxos de segurança exigidos pela plataforma.
Exemplo Completo:
final credential = await SignInWithApple.getAppleIDCredential( scopes: [AppleIDAuthorizationScope.email, AppleIDAuthorizationScope.fullName], ); print(credential.userIdentifier);
19. Image Picker
A ferramenta padrão para permitir que o usuário selecione fotos da galeria ou tire uma foto nova com a câmera.
Exemplo Completo:
final ImagePicker picker = ImagePicker();
final XFile? image = await picker.pickImage(source: ImageSource.gallery);
if (image != null) {
print('Caminho da imagem: ${image.path}');
}
20. Connectivity Plus
Favorito para gerenciar estados de conexão. Permite que o app saiba se está no Wi-Fi, 4G/5G ou sem internet, permitindo que você avise o usuário ou pause downloads.
Exemplo Completo:
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult.contains(ConnectivityResult.mobile)) {
print("Conectado via rede móvel");
}
📊 Resumo de Escolha Técnica
| Se o seu objetivo é… | Utilize… |
| Arquitetura e Estado | Riverpod |
| Integração com IA Agêntica | Mcp_server |
| Segurança de Tokens | Flutter Secure Storage |
| Persistência Reativa (SQL) | Drift |
🎨 Tabela de Utilidade: Expansão da Lista
| Categoria | Pacote | Uso Principal |
| Arquivos/Sistema | Path Provider / Shared Prefs | Armazenar dados e arquivos simples. |
| Mídia | Video Player / Image Picker | Lidar com fotos e vídeos. |
| Visual | Google Fonts / Cached Image | Melhorar estética e performance visual. |
| Integração | Url Launcher / Connectivity | Interagir com o SO e estado da rede. |
Esta é uma excelente combinação para melhorar a experiência do utilizador (UX). Ao integrar o Connectivity Plus com o Cached Network Image, podes criar uma lógica onde o teu aplicativo só tenta carregar imagens de alta qualidade se estiver numa rede Wi-Fi, ou exibir uma versão em cache/baixa qualidade se estiver em dados móveis.
Aqui tens um guia completo e um exemplo de código profissional para implementar este sistema:
📘 Artigo: Sistema Inteligente de Imagens com Flutter
Neste cenário, vamos construir um componente que:
-
Verifica o estado da rede.
-
Se estiver em Wi-Fi, carrega a imagem normalmente.
-
Se estiver em Dados Móveis, exibe um aviso ou carrega uma versão otimizada.
-
Se estiver Offline, tenta recuperar apenas o que já está no cache.
🛠️ Dependências Necessárias
Adiciona estas linhas ao teu pubspec.yaml:
💻 Exemplo de Código Completo
import 'package:flutter/material.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:cached_network_image/cached_network_image.dart';
class SmartImageLoader extends StatelessWidget {
final String imageUrl;
const SmartImageLoader({super.key, required this.imageUrl});
// Função para verificar o tipo de conexão
Future<List<ConnectivityResult>> _checkConnectivity() async {
return await (Connectivity().checkConnectivity());
}
@override
Widget build(BuildContext context) {
return FutureBuilder<List<ConnectivityResult>>(
future: _checkConnectivity(),
builder: (context, snapshot) {
final connectivity = snapshot.data;
bool isWifi = connectivity?.contains(ConnectivityResult.wifi) ?? false;
bool isOffline = connectivity?.contains(ConnectivityResult.none) ?? true;
return CachedNetworkImage(
imageUrl: imageUrl,
// Se estiver offline, força a leitura apenas do cache
memCacheHeight: isWifi ? null : 200, // Reduz qualidade se não for Wi-Fi
placeholder: (context, url) => const Center(
child: CircularProgressIndicator(),
),
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
colorFilter: isOffline
? const ColorFilter.mode(Colors.grey, BlendMode.saturation)
: null, // Fica cinza se estiver offline
),
),
),
errorWidget: (context, url, error) => const Icon(Icons.signal_wifi_off),
);
},
);
}
}
🧐 Por que esta abordagem é “Favorite”?
-
Economia de Dados: Ao usar o
memCacheHeightoumaxWidthdinamicamente com base na conexão, evitas o download de ficheiros pesados em redes 4G/5G. -
Feedback Visual: O filtro de saturação (cinza) no
imageBuilderindica ao utilizador que aquela imagem é antiga (cache) e que ele está sem internet no momento. -
Performance: O Cached Network Image gere automaticamente o armazenamento no disco, para que a imagem não seja descarregada duas vezes, mesmo que feches o app.