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:

  1. Verifica o estado da rede.

  2. Se estiver em Wi-Fi, carrega a imagem normalmente.

  3. Se estiver em Dados Móveis, exibe um aviso ou carrega uma versão otimizada.

  4. 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”?

  1. Economia de Dados: Ao usar o memCacheHeight ou maxWidth dinamicamente com base na conexão, evitas o download de ficheiros pesados em redes 4G/5G.

  2. Feedback Visual: O filtro de saturação (cinza) no imageBuilder indica ao utilizador que aquela imagem é antiga (cache) e que ele está sem internet no momento.

  3. 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.

🔗 Links Oficiais:

Please follow and like us:
error0
fb-share-icon
Tweet 20
fb-share-icon20