Top Flutter packages for production apps in 2026
By Ann Tech · 28 May 2025
These are packages that have proven themselves in production Flutter apps: well-maintained, widely used, and solving real problems without unnecessary complexity. Updated for 2026.
State management
flutter_bloc / bloc
The most mature solution for large apps. Explicit events and states make data flow predictable and testable.
dependencies:
flutter_bloc: ^8.1.5
bloc: ^8.1.4
Best for: complex state transitions, teams who value testability.
riverpod
Compile-safe with less boilerplate. @riverpod code generation makes providers concise.
dependencies:
flutter_riverpod: ^2.5.1
riverpod_annotation: ^2.3.5
dev_dependencies:
riverpod_generator: ^2.4.0
Best for: medium-complexity apps.
Networking
dio
The standard HTTP client. Interceptors for auth, logging, retry; multipart upload; cancellation.
final dio = Dio(BaseOptions(
baseUrl: 'https://api.example.com',
connectTimeout: const Duration(seconds: 5),
receiveTimeout: const Duration(seconds: 10),
));
dio.interceptors.add(InterceptorsWrapper(
onRequest: (options, handler) {
options.headers['Authorization'] = 'Bearer ${authService.token}';
handler.next(options);
},
));
retrofit
Type-safe API client on top of Dio:
@RestApi(baseUrl: 'https://api.example.com')
abstract class ApiClient {
factory ApiClient(Dio dio) = _ApiClient;
@GET('/orders')
Future<List<Order>> getOrders();
@POST('/orders')
Future<Order> createOrder(@Body() CreateOrderRequest request);
}
Local storage
drift
Type-safe SQLite. The right choice for relational data and complex queries.
dependencies:
drift: ^2.18.0
sqlite3_flutter_libs: ^0.5.23
dev_dependencies:
drift_dev: ^2.18.0
hive_flutter
Fast key-value store for caching non-relational data.
shared_preferences
Simple settings storage.
Dependency injection
get_it + injectable
@injectable
class OrderRepository {
OrderRepository(this._api, this._cache);
final ApiClient _api;
final OrderCache _cache;
}
await configureDependencies();
final repo = getIt<OrderRepository>();
Navigation
go_router
The Flutter team's recommended router. Declarative, deep-link-aware, nested navigation.
dependencies:
go_router: ^14.0.0
Code generation
freezed
Immutable data classes with copyWith and sealed class support:
@freezed
class OrderState with _$OrderState {
const factory OrderState.initial() = _Initial;
const factory OrderState.loading() = _Loading;
const factory OrderState.loaded(List<Order> orders) = _Loaded;
const factory OrderState.error(String message) = _Error;
}
json_serializable
@JsonSerializable()
class Order {
final String id;
final double total;
factory Order.fromJson(Map<String, dynamic> json) => _$OrderFromJson(json);
Map<String, dynamic> toJson() => _$OrderToJson(this);
}
Firebase
Standard suite: firebase_core, cloud_firestore, firebase_auth, firebase_storage, firebase_crashlytics, firebase_analytics.
// Always set up Crashlytics in main.dart
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
UI packages
cached_network_image
CachedNetworkImage(
imageUrl: product.imageUrl,
placeholder: (_, __) => const ProductImageSkeleton(),
errorWidget: (_, __, ___) => const Icon(Icons.broken_image),
)
flutter_svg — SVG rendering for icons and illustrations.
shimmer — Skeleton loading animations. Replaces spinners for structured content.
gap — Clean spacing in Column/Row:
Column(children: [
const Text('Title'),
const Gap(16),
const Text('Subtitle'),
])
Testing
mocktail
Null-safe mocking without codegen:
class MockOrderRepository extends Mock implements OrderRepository {}
when(() => repo.getOrders()).thenAnswer((_) async => [order1]);
Utilities
- intl: date formatting, pluralization, number formatting
- url_launcher: open URLs, email links, phone numbers
- package_info_plus: app version and build number
- permission_handler: unified permission API for iOS and Android
Common pitfalls
Adding a package for every problem. Each package adds binary size and maintenance overhead. Check if 20 lines of Dart would do it.
Not checking pub.dev scores. A package last updated 3 years ago with low pub points is a maintenance risk.
Pinning to exact versions. dio: 5.4.3 (no caret) blocks security updates. Use ^5.4.3.
Sign in to like, dislike, or report.