← Articles

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>();

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.

Top Flutter packages for production apps in 2026 — ANN Tech