levit_flutter
The Flutter integration layer for the Levit framework. Declarative. Precise. Non-invasive.
levit_flutter bridges Levit’s pure Dart core into Flutter’s widget tree. It connects the reactivity of levit_reactive and the lifecycle discipline of levit_dart to Flutter without altering Flutter’s mental model.
This package does not replace Flutter concepts—it composes with them.
What levit_flutter Is (and Is Not)
levit_flutter is a binding layer, not a framework rewrite.
- It does not introduce a new widget paradigm
- It does not hide Flutter primitives
- It does not impose global rebuilds or magic observers
Instead, it provides explicit widgets and extensions that let Flutter opt into Levit’s reactivity and dependency scoping where it makes sense.
Features
-
LWatchA fine-grained reactive widget. Rebuilds only when accessedLxvalues change. -
LevitControllerA Flutter-aware controller with automatic lifecycle wiring (onInit,onDispose). -
LStatusBuilderDeclarative rendering for async state (waiting, error, success) driven by reactive sources. -
LScopeWidget-tree–scoped dependency injection with deterministic teardown. -
Context Extensions Ergonomic, type-safe access to Levit DI from
BuildContext.
Installation
dependencies:
levit_flutter: ^latest
import 'package:flutter/material.dart';
import 'package:levit_flutter/levit_flutter.dart';
Quick Start
Reactive UI with LWatch
LWatch automatically tracks any Lx value accessed during build and rebuilds only when those values change.
final count = 0.lx;
LWatch(() => Text(
'Count: ${count.value}',
style: const TextStyle(fontSize: 24),
));
There are no manual listeners, no disposers, and no global rebuilds.
Controller-Driven State with LevitController
Move logic out of widgets while keeping lifecycle guarantees.
class CounterController extends LevitController {
late final count = autoDispose(0.lx);
void increment() {
count.value++;
}
}
autoDispose ensures all reactive resources are released when the controller leaves scope.
Declarative Async UI with LStatusBuilder
Render async state without boilerplate or imperative checks.
class UserProfile extends StatelessWidget {
@override
Widget build(BuildContext context) {
final controller = context.levit.find<UserController>();
return LStatusBuilder(
source: controller.userFuture,
onWaiting: () => const CircularProgressIndicator(),
onError: (error, _) => Text('Error: $error'),
onSuccess: (user) => Text('Hello, ${user.name}'),
);
}
}
LStatusBuilder works with LxFuture and LxStream from levit_reactive.
Dependency Injection & Widget Scoping
Use LScope to bind controllers and services to a widget subtree.
LScope(
init: () => ProfileController(),
child: const ProfileView(),
);
Inside the subtree:
final controller = context.levit.find<ProfileController>();
When LScope is removed:
ProfileController.onDispose()is called- All tracked reactive resources are released
- No global state leaks occur
Architectural Role
In the Levit stack:
levit_reactivedefines reactive primitiveslevit_didefines dependency scopinglevit_dartdefines application structurelevit_flutterprojects all of the above into Flutter’s widget tree
Each layer remains usable independently.
Design Principles
- Flutter-first mental model
- Explicit rebuild boundaries
- Deterministic lifecycles
- Zero hidden global observers
levit_flutter exists to let Flutter applications scale in complexity without scaling rebuild cost or cognitive load.
Libraries
- levit_flutter
- Flutter widgets for the Levit framework.