Skip to content

Instantly share code, notes, and snippets.

@evaisse
Last active September 2, 2025 23:49
Show Gist options
  • Select an option

  • Save evaisse/b8fa9259bc31fbc0839d1062da3b7447 to your computer and use it in GitHub Desktop.

Select an option

Save evaisse/b8fa9259bc31fbc0839d1062da3b7447 to your computer and use it in GitHub Desktop.
Development Stack with Flutter

Development Stack with Flutter

  • Flutter app, with provider for dependency management.
  • Always run flutter analyze to fix all errors, when there is errors, just run dart fix --apply before trying to manipulate the code by yourself
  • Always ensure your code is fully tested, with flutter test() or widgetTest(), add be generous with goldenTest and screen captures also
  • Always prefer type-safe alternative to dynamic, late and other risky behaviors
  • Do not cast with as keyword, but always prefer pattern matching to safely cast and test types
  • Never use the dynamic keyword, nor late, but prefer Object? which is safer
  • Always use flutter theme extension to allow UI customization, for every group of UI widgets you build, add a theme extension and refer to hit using context to customize the widgets.
  • Always prefer developer.log to print() and debugPrint(), you can write extensive logging
  • Please don't unwrap state.pathParameters['id']!; nor cast unsafely state.extra as MyCard;. Prefer usage of lib package:castor/castor.dart and convert to state.extra.castOrNull<TarotCard>() and works with nullable.
  • For provider, prefer usage of context.read(), context.select() and context.watch() instead of Consumer<Xxx>
  • Prefer enums, static properties and other staticaly analyzed values instead of string-based calls context.navigate('/draw').
  • When you create a package, always provide an ./example app with extensive examples and documentation.
  • For testing and mocking, instead of relying on various packages, just simply wrap service into provider injection that you will override in tests environments.
  • All code and documentation in English

For typesafety, you can use the https://pub.dev/packages/castor as dependency

import 'package:castor/castor.dart';
import 'dart:convert';

void main() {
  final dyn = jsonDecode('stuff'); // this is `dynamic`
  final obj = (dyn as Object?);
  // the basic [castOr] always expect to get an uwrapped value of the input type    
  int b = obj.castOr<String>(a, (_) => 'alternative string').length;
  int c = castOr<int>(a, (_) => 'alternative string').length;
  
  // the [castOrNull] equivalent just accept a nullable when casting is wrong
  bool? asHelper = castOrNull<bool>(a, (_) => 'alternative string').length;
  bool? asExt = obj?.castOrNull();
  
  int? s = castOrNull<String>(a)?.length;
  /// and with [a] an Object?
  int s2 = a?.castOr<String>((val) => 'alternative string').length;
  int? s = a?.castOrNull<String>(a)?.length;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment