Skip to content

Instantly share code, notes, and snippets.

View evaisse's full-sized avatar

Emmanuel Vaïsse evaisse

  • none
  • Nancy, France
View GitHub Profile

Copyright :

There are countless Flutter coding conventions floating around. From the popular “Flutter Clean Architecture” to community-driven style guides, developers have been following external conventions for years. I was one of them.

For the past 5 years, I followed community best practices, enforced strict linting rules, and structured my Flutter apps according to popular Medium articles and YouTube tutorials. My code was “clean,” and my architecture was “proper.”

But everything changed when I started studying how Google’s Flutter team actually writes Flutter code.

@evaisse
evaisse / GEMINI.md
Last active September 2, 2025 23:49
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.
@evaisse
evaisse / main.dart
Last active August 14, 2025 17:31
using provider to lazy load service disregarding the widget tree order.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ServiceBuilder<T extends Service> {
final T Function(BuildContext context) create;
ServiceBuilder(this.create);
Provider<T> asProvider(ValueNotifier<BuildContext> scope) =>
Provider<T>(create: (_) => create(scope.value));
@evaisse
evaisse / main.dart
Last active June 30, 2025 13:59
Describing usage of context.select/read/watch etc
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
/// Represents a city using a record, with its name (including flag emoji),
/// population, and seaside status.
/// Records provide automatic equality and hash code implementation.
typedef City = ({String name, int population, bool isSeaside});
/// Manages the selection of a city and provides available city data.
///
@evaisse
evaisse / main.dart
Last active June 30, 2025 13:19
ChangeNotifier with provider
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
/// Data model for the counter, extending ChangeNotifier to notify listeners of changes.
class CounterData extends ValueNotifier<int> {
CounterData() : super(0);
void increment() => value = value + 1;
}
@evaisse
evaisse / doc_returns_types_for_function.dart
Last active June 19, 2025 14:13
doc_returns_types_for_function.dart
/// Attention à TOUJOURS typer le retour des callback/builders
/// que vous allez passer aux widgets/controllers.
class Foo {
Function()? onFoo;
void Function()? onFoufou;
Foo({ this.onFoo, this.onFoufou });
}
void main() {
@evaisse
evaisse / copywith_nullable.dart
Last active June 5, 2025 14:14
copyWith with nullable and optional
/// General demonstration about the annoying way to set to null a copy of another object
///
/// @see https://github.com/dart-lang/language/issues/877
/// @see https://stackoverflow.com/questions/68009392/dart-custom-copywith-method-with-nullable-properties
class Person {
final String name;
final String? nickName;
Person({required this.name, this.nickName});
@evaisse
evaisse / pointy_castle_asymmetric_encryption.dart
Created March 11, 2025 09:12
Asymmetric Encryption RSA-AES-CBC with public/private keys using pointycastle lib
import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';
import 'package:basic_utils/basic_utils.dart';
import 'package:encrypt/encrypt.dart';
// ignore: depend_on_referenced_packages
import 'package:crypto/crypto.dart';
import 'package:flutter/foundation.dart' as flutter;
import 'package:pointycastle/export.dart';
@evaisse
evaisse / main.dart
Created February 11, 2025 15:20
Algrebraic data types
// Définition d'une classe scellée pour représenter un résultat
// Sealed class : https://dart.dev/language/class-modifiers#sealed
sealed class ASealedClass {}
// cas 1
class Success extends ASealedClass {}
// cas 2
class Failure extends ASealedClass {}
/// sous la forme d'un enum
enum AnEnum { success, error }
@evaisse
evaisse / the_problem_with_dynamic.dart
Created September 13, 2024 14:17
The problem with `dynamic` in dart
void main() {
dynamic myDynamicValue = null;
myDynamicValue.length;
Object? myTypedValue = myDynamicValue;
myTypedValue.length; // that's helpful