# Piper State > Flutter state management that cleans up after itself. Piper puts state, derived values, streams, and async tasks in plain Dart ViewModels. Automatic rebuilds follow tracked reads, while stream cleanup and cooperative task cancellation follow the ViewModel lifecycle. ## Documentation - Documentation: https://glennso.dev/piper/ - GitHub: https://github.com/theGlenn/piper ## Quick Start Install: ```yaml dependencies: flutter_piper: ^0.1.0 ``` `flutter_piper` re-exports the core `piper_state` API. Pure Dart projects can install `piper_state` directly. Basic ViewModel: ```dart class CounterViewModel extends ViewModel { late final count = state(0); void increment() => count.update((c) => c + 1); } ``` Use in widgets: ```dart ViewModelScope( create: [() => CounterViewModel()], child: MyApp(), ) // Access in widgets final vm = context.vm(); vm.count.build((count) => Text('$count')) ``` ## Core Concepts ### StateHolder Synchronous state container: - `state(initialValue)` - Create state - `value` - Read/write - `update((v) => newV)` - Transform - `build((v) => Widget)` - Reactive UI ### AsyncStateHolder Async state with loading/error/data: - `asyncState()` - Create - `load(state, () => Future)` - Load with lifecycle - States: `AsyncEmpty`, `AsyncLoading`, `AsyncError`, `AsyncData` - Helpers: `isLoading`, `hasData`, `hasError`, `dataOrNull` - `setErrorFrom(error)` - Preserve the error object and stack trace ### Watch & Computed Automatic dependency tracking: - `Watch((context) => Widget)` - Rebuilds from any state read in the builder - `computed(() => value, {equals})` - Derived state, recomputes on dependency change - Reads are tracked, writes are not; cycles throw; notifications are batched ### Stream Bindings - `bind(stream, initial: value)` - Bind stream to StateHolder - `bindAsync(stream)` - Bind to AsyncStateHolder - `stateFrom(stream, initial: v, transform: fn)` - Transform types - `subscribe(stream, callback)` - Manual handling ### Task Cancellable async operations: - `launch((cancellation) => Future)` - Returns Task handle - `cancellation.wait(future)` - Stops the task body on cancellation - `cancellation.onCancel(abort)` - Connects an underlying abort API - `launchWith((cancellation) => Future, ...)` - With callbacks - `task.cancel()` - Request cooperative cancellation - Auto-cancels on ViewModel dispose ### ViewModelScope Widget tree integration: - `ViewModelScope(create: [...], child: Widget)` - Multiple VMs - `Scoped(create: () => VM, builder: (ctx, vm) => Widget)` - Single VM - `context.vm()` - Access ViewModel - Named scopes for multi-step flows ## Key Features - **Automatic Rebuilds**: `Watch` subscribes to the state it reads - **Lifecycle-Owned Cleanup**: Streams and cooperative tasks stop on dispose - **Explicit Dependencies**: Constructor injection keeps the graph visible - **Plain Dart**: No code generation; test business logic without Flutter - **Incremental**: Works alongside existing solutions ## Links - Guide: https://glennso.dev/piper/guide/what-is-piper - Examples: https://glennso.dev/piper/examples/counter - API Reference: https://glennso.dev/piper/llms-full.txt