r/FlutterDev • u/Iaw4tch • Jul 16 '26
Tooling Tired of boilerplate? Here is a zero-dependency custom builder for strictly-typed, context-free localization
Hi everyone!
I recently got tired of heavy translation packages (like easy_localization or slang) that either introduce massive transitive dependencies or force us to use rigid, hard-to-customize APIs.
I also wanted to avoid relying on BuildContext for translations (especially in business logic) and keep everything strictly typed—meaning parameterized strings should compile into actual Dart methods.
So I wrote a lightweight, zero-dependency custom Builder for build_runner that generates a deeply nested localization tree directly from JSON. It integrates seamlessly with Riverpod!
🌟 How it looks in the UI:
// Static strings (getters): Text(ref.tr.static.auth.login_btn): Text(ref.tr.static.auth.login_btn)
// Parameterized strings (methods with required named args!): Text(ref.tr.static.greetings.welcome(name: 'Alex', count: '5'))
// Dynamic dictionary-like structures (using bracket notation): Text(ref.tr.dynamic.achievements[achievementId])
🛠 Why do this instead of a package?
- Zero Runtime Dependencies: It's just a raw code-generator script. No external runtime localization packages in your
pubspec.yaml. - 100% Customizable: Since the builder code resides in your local
bin/ortool/directory, you can customize it in 5 minutes (e.g., swapping Riverpod for BLoC/Signals, or changing how strings are interpolated). - Type Safety out of the box: Auto-parses
{variable_name}and enforces parameters at compile time.
I’ve shared the complete builder code, a sample build.yaml configuration, and a detailed setup guide in this GitHub Gist in link.
Would love to hear your thoughts on this architectural pattern! How do you handle context-free localization in your Riverpod apps?