"State that drips to the metal."
Sub-widget reactive state for Flutter. State changes propagate directly to RenderObject property setters — zero widget rebuilds, zero setState().
| Package | Version | Status | Description |
|---|---|---|---|
drip_core |
1.0.0 |
Pure Dart reactive engine — DripState, DripComputed, DripEffect, DripScope, DripTrace |
|
drip_flutter |
0.7.0-alpha |
Flutter render layer — DripText, DripOpacity, DripLifecycle, DripSemantics, DripItems, DripItemBuilder |
|
drip_gen |
planned | Planned | Code generator + CLI |
drip_native |
planned | Planned | FFI shared memory native bridge |
State.write() → DripBatch (microtask) → DripBinding → RenderObject.markNeedsPaint() → paint
↑
zero Widget.build() calls
No widget tree traversal. No diffing. No setState().
See ARCHITECTURE.md for the 7 invariants that govern every line of code.
import 'package:drip_core/drip_core.dart';
final count = dripState(0);
final doubled = DripComputed(() => count.value * 2);
DripEffect(() => print('count: ${count.value}, doubled: ${doubled.value}'));
count.write(5);
// → prints: "count: 5, doubled: 10"import 'package:drip_flutter/drip_flutter.dart';
final label = dripState('Hello');
// In build() — no setState ever needed:
DripText(label, style: TextStyle(fontSize: 24))
// Anywhere else:
label.write('World'); // Updates RenderParagraph directly. 0 widget builds.class CounterNode extends DripNode {
late final DripState<int> count;
late final DripComputed<String> displayText;
@override
void onInit() {
count = state(0);
displayText = computed(() => count.value.toString());
}
}
// In your widget tree (Context-Free Injection):
DripLifecycle<CounterNode>(
create: () => CounterNode(),
builder: (node) => DripText(node.displayText),
)// Enable synchronous stack trace capturing for state mutations
DripTrace.enabled = true;
final count = dripState(0, debugName: 'counter');
// If an effect fails, the stack trace will chain back to the exact write call.Upgrading from an older version of DRIP? Please read MIGRATION.md for step-by-step instructions on replacing deprecated provider, route-node, and list APIs with DripLifecycle, DripItems, and DripItemBuilder.
| Version | Status | Description |
|---|---|---|
v0.1.1-alpha |
✅ Released | Reactive engine — DripState, DripComputed, DripEffect, DripScope |
v0.2.0-alpha |
✅ Released | Flutter render layer — DripText, DripOpacity, DripColor, DripTransform, DripImage |
v0.3.0-alpha |
✅ Released | Node architecture — DripNode, DripNodeProvider, DripRouteNode, DripList, DripListView |
v0.4.0-alpha |
✅ Released | Async layer — DripAsync, DripAsyncValue, DripAsyncBuilder, DripSelect, DripAsyncNode |
v0.5.1-alpha |
✅ Released | Phase 5: Stability — Diagnostic tracing, Semantics bridge, Lifecycle widgets, Context-free enforcement |
drip_core 1.0.0 |
✅ Ready | Stable core API, coverage gate, benchmark regression checks |
drip_flutter 0.6.0-alpha |
✅ Ready | Deprecated provider, route-node, and list APIs removed |
drip_flutter 0.7.0-alpha |
✅ Ready | Flutter API freeze for the pre-1.0 line |
drip_flutter 1.0.0 |
Planned | DevTools extension, migration guides, stress testing |
Prerequisites: Melos
# Install Melos
dart pub global activate melos
# Link all local packages
dart pub global run melos bootstrap# Run all tests
dart pub global run melos test
# Static analysis (zero-tolerance)
dart pub global run melos analyze
# Format
dart pub global run melos format
# Publish dry-run
dart pub global run melos publish:dryOr use the short aliases if melos is on your PATH:
melos bootstrap && melos run analyze && melos run testMIT © 2026 DRIP Contributors