Flutter Zero: A go-zero-Inspired MVI-BLoC Scaffold That Generates Your Entire Feature Module
Flutter developers starting new projects repeatedly write the same BLoC boilerplate, wire up dependency injection, and struggle with side-effect management. This toolchain automates the scaffolding and provides a composable Mixin architecture that solves common pain points—like awaiting event completion, canceling in-flight requests on page exit, and keeping side effects out of State—without forcing a rigid, one-size-fits-all framework.
Flutter Zero is a toolchain that automates the creation of feature modules in Flutter, inspired by Go's go-zero framework. Its CLI, `fluzer`, generates a full set of files for a feature, including a BLoC with four specialized Mixins for awaiting events, managing side effects, canceling network requests, and handling errors through a Kotlin-style `Result` type. The architecture strictly separates UI state from one-time side effects like Toasts and dialogs using an independent Stream and a chain-of-responsibility pattern, allowing new effect types to be added without modifying framework code. The system also includes a type-safe internationalization code generator that defers translation to the UI layer, keeping BLoCs free of context dependencies. Dependency injection is managed through a template method pattern that automatically registers new modules via AST manipulation, and network request lifecycles are tied to page lifecycles to prevent zombie callbacks.
Manually calling `completeAwait` in a BLoC's event handler is a leaky abstraction because an early return or a missed finally block can hang a Future indefinitely; the `onAwait` wrapper eliminates this by guaranteeing completion in a finally block.
Using an abstract class instead of a sealed class for `UIEffect` is a deliberate trade-off: it sacrifices compile-time exhaustiveness checking in favor of allowing any feature module to define custom side effects without modifying the framework's core library.
Refusing to normalize exceptions into a custom framework exception tree avoids making incorrect business assumptions about error codes and message formats, but it shifts the burden of consistent error handling onto individual BLoC implementations.
The `BlocCancelTokenMixin` design, where requesting a token with the same key automatically cancels the previous one, bakes a debounce-like deduplication directly into the network layer without requiring explicit cancel logic in business code.
Generating L10nCode factory constructors from `.arb` files makes the localization call-site type-safe, catching missing or misspelled keys at compile time rather than at runtime, which is a significant ergonomic improvement over raw string keys.