Production Guide
Strategies for building scalable, responsive, and performant Fluxy applications.
Production-Grade Fluxy
Building a production application requires structure. This guide covers how to scale Fluxy effectively using the Feature-First pattern.
1. Professional Workflow
For every new feature, follow this order:
1. Define Logic (The Controller)
Write your logic in auth.controller.dart. Do not touch UI.
// lib/features/auth/auth.controller.dart
class AuthController extends FluxController {
final email = fluxField("");
final password = fluxField("");
final isSubmitting = flux(false);
Future<void> submit() async {
isSubmitting.value = true;
await _repo.login(email.value, password.value);
isSubmitting.value = false;
}
}2. Define Layout Shell
Use Fx.page or Fx.dashboard for structure in auth.view.dart.
// lib/features/auth/auth.view.dart
Fx.page(
appBar: Fx.text("Login").h3(),
body: LoginForm(),
)3. Assemble Atomic Components
Combine generic signals with .input() and .btn() DSL.
final controller = AuthController();
Fx.col().children([
// Inputs bind directly to signals (No text controllers needed)
FxTextField(
signal: controller.email,
placeholder: "Enter Email",
icon: Icons.email,
style: FxStyle(padding: EdgeInsets.all(16)),
validators: [(val) => !val.contains('@') ? "Invalid" : null],
),
FxTextField(
signal: controller.password,
placeholder: "Enter Password",
obscureText: true,
),
// States reflected in UI
Fx(() => controller.isSubmitting.value
? Fx.loader()
: "Login".primaryBtn(onTap: controller.submit))
])2. Advanced Responsiveness
Fluxy removes the need for LayoutBuilder by providing breakpoint-aware modifiers.
- Adaptive Width:
.wFull().width(md: 400)-> Full width on mobile, fix to 400px on tablet. - Grid Systems: Use
Fx.grid()over standardGridViewfor better responsive control. - Conditional Rendering:
.hideOnMobile()or.showPayload(lg: ...)
3. Performance Optimization
Fluxy's core advantage is minimal rebuilds.
Granular Observers (FxObserver)
Instead of rebuilding an entire Scaffold, wrap only the text node that changes.
// BAD
Fx(() => Fx.scaffold(
body: Fx.text("Count: ${count.value}")
));
// GOOD (Only the text rebuilds)
Fx.scaffold(
body: Fx(() => Fx.text("Count: ${count.value}"))
);Avoid Heavy Computations in UI
Use computedFlux (or similar reactive derivations) to perform math outside the build method.
final cartTotal = flux(() => items.fold(0, (p, c) => p + c.price));
// UI just reads the value
Fx(() => Fx.text("\$${cartTotal.value}")) 4. Error Handling
Fluxy encourages explicit error handling in your logic layer rather than UI try/catch.
final errorMsg = flux<String?>(null);
Future<void> fetchData() async {
try {
// ... fetch ...
} catch (e) {
errorMsg.value = e.toString();
// Use Fx.toast or Fx.snackbar based on your logic
}
}
// In UI:
Fx(() => errorMsg.value != null
? Fx.text(errorMsg.value!).color(Colors.red)
: Fx.box())By sticking to these simple primitives—Controllers, Atomic DSL, and Responsive Modifiers—you ensure your app remains lightweight and bug-free.
What's next?
Read the Hardening Guide to learn about Error Boundaries, Industrial Vaults, and Resource Efficiency.