
Redux-style state management: reducer pattern, middleware, execution strategies (takeLatest, debounce, throttle, retry), strategy chaining, error processors, time-travel debugging, and real-time WebSocket state synchronization with type-safe shared actions.
A lightweight Redux-style state management library for Kotlin Multiplatform and Dart/Flutter with Middleware support.
ServerSharedAction / ClientSharedAction)kotlinx.serialization
Add the dependency to your KMP project's build.gradle.kts:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.chibimoons:flowdux:1.17.0")
}
}
}Gradle automatically resolves the correct artifact for each target (JVM, iOS, JS, WASM).
If your project is not KMP, add the dependency directly:
dependencies {
implementation("io.github.chibimoons:flowdux:1.17.0")
}For real-time client-server state sync, add the relevant modules:
kotlin {
sourceSets {
commonMain.dependencies {
// Shared action markers (ServerSharedAction, ClientSharedAction)
implementation("io.github.chibimoons:flowdux-remote-core:1.17.0")
// Client middleware (SyncMiddleware)
implementation("io.github.chibimoons:flowdux-remote-client:1.17.0")
// Server middleware (SingleClientSyncMiddleware, MultiClientSyncMiddleware)
implementation("io.github.chibimoons:flowdux-remote-server:1.17.0")
// kotlinx.serialization codecs (ActionCodec, MessageCodec)
implementation("io.github.chibimoons:flowdux-remote-serialization:1.17.0")
// Ktor WebSocket transport (JVM, iOS, JS — WASM not supported)
implementation("io.github.chibimoons:flowdux-remote-ktor:1.17.0")
}
}
}Add JitPack repository to your settings.gradle.kts:
dependencyResolutionManagement {
repositories {
maven { url = uri("https://jitpack.io") }
}
}dependencies {
implementation("com.github.chibimoons:flowdux:1.10.0")
}Add to your pubspec.yaml:
dependencies:
flowdux: ^0.3.2Add to your pubspec.yaml:
dependencies:
flowdux: ^0.3.2
flowdux_flutter: ^0.3.2data class CounterState(val count: Int = 0) : State
sealed class CounterAction : Action {
object Increment : CounterAction()
object Decrement : CounterAction()
data class Add(val value: Int) : CounterAction()
}val counterReducer = buildReducer<CounterState, CounterAction> {
on<CounterAction.Increment> { state, _ ->
state.copy(count = state.count + 1)
}
on<CounterAction.Decrement> { state, _ ->
state.copy(count = state.count - 1)
}
on<CounterAction.Add> { state, action ->
state.copy(count = state.count + action.value)
}
}class LoggingMiddleware : Middleware<CounterState, CounterAction> {
override val processors = buildProcessors {
on<CounterAction.Increment> { state, action ->
println("Incrementing from ${state.count}")
emit(action)
}
}
}class CounterErrorProcessor : ErrorProcessor<CounterAction> {
override fun process(throwable: Throwable): Flow<CounterAction> = flow {
println("Error: ${throwable.message}")
}
}val store = createStore(
initialState = CounterState(),
reducer = counterReducer,
middlewares = listOf(LoggingMiddleware()),
errorProcessor = CounterErrorProcessor(),
scope = viewModelScope
)
// Observe state
store.state.collect { state ->
println("Current count: ${state.count}")
}
// Dispatch actions
store.dispatch(CounterAction.Increment)
store.dispatch(CounterAction.Add(10))Always call close() when the store is no longer needed to release resources:
// In ViewModel
override fun onCleared() {
store.close()
super.onCleared()
}isClosed Property:
Check isClosed before dispatching if there's a possibility the store may be closed:
if (!store.isClosed) {
store.dispatch(action)
}Note: Dispatching after close() is logged via StoreLogger.onDispatchAfterClose() and may indicate a bug in your application.
| Topic | Description |
|---|---|
| Architecture | Store pipeline, middleware chain, action flow |
| Execution Strategies | takeLatest, debounce, throttle, retry, groups, chaining |
| Remote (WebSocket) | Client-server state sync, authentication, server patterns |
| Time Travel | Undo/redo, state history, branching |
| Sample Apps | How to run each sample |
| Dart/Flutter | Dart API, Flutter widgets, stream integration |
FlowDux 1.17.0 is built with Kotlin 2.2.10. For best compatibility, use the same Kotlin version in your project:
plugins {
kotlin("multiplatform") version "2.2.10"
kotlin("plugin.serialization") version "2.2.10" // if using remote modules
}Using a different Kotlin version may cause compilation errors, especially on iOS and JS targets.
When using flowdux-remote modules with kotlinx.serialization, use version 1.7.3 or compatible:
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")| Platform | Status |
|---|---|
| JVM | ✅ |
| iOS | ✅ |
| JS | ✅ |
| WASM | ❌ (Ktor client not available) |
| Platform | Status | Sample |
|---|---|---|
| JVM | ✅ | kotlin/samples/jvm |
| JVM (Remote/WebSocket) | ✅ | kotlin/samples/remote-chat |
| Android | ✅ |
kotlin/samples/android, kotlin/samples/shared/androidApp
|
| iOS | ✅ | kotlin/samples/shared/iosApp |
| JavaScript | ✅ | kotlin/samples/web |
| WebAssembly | ✅ | kotlin/samples/wasm |
| Platform | Status | Sample |
|---|---|---|
| Dart | ✅ | dart/flowdux |
| Flutter | ✅ | dart/flowdux_flutter |
Copyright 2024 Flowdux Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
A lightweight Redux-style state management library for Kotlin Multiplatform and Dart/Flutter with Middleware support.
ServerSharedAction / ClientSharedAction)kotlinx.serialization
Add the dependency to your KMP project's build.gradle.kts:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.chibimoons:flowdux:1.17.0")
}
}
}Gradle automatically resolves the correct artifact for each target (JVM, iOS, JS, WASM).
If your project is not KMP, add the dependency directly:
dependencies {
implementation("io.github.chibimoons:flowdux:1.17.0")
}For real-time client-server state sync, add the relevant modules:
kotlin {
sourceSets {
commonMain.dependencies {
// Shared action markers (ServerSharedAction, ClientSharedAction)
implementation("io.github.chibimoons:flowdux-remote-core:1.17.0")
// Client middleware (SyncMiddleware)
implementation("io.github.chibimoons:flowdux-remote-client:1.17.0")
// Server middleware (SingleClientSyncMiddleware, MultiClientSyncMiddleware)
implementation("io.github.chibimoons:flowdux-remote-server:1.17.0")
// kotlinx.serialization codecs (ActionCodec, MessageCodec)
implementation("io.github.chibimoons:flowdux-remote-serialization:1.17.0")
// Ktor WebSocket transport (JVM, iOS, JS — WASM not supported)
implementation("io.github.chibimoons:flowdux-remote-ktor:1.17.0")
}
}
}Add JitPack repository to your settings.gradle.kts:
dependencyResolutionManagement {
repositories {
maven { url = uri("https://jitpack.io") }
}
}dependencies {
implementation("com.github.chibimoons:flowdux:1.10.0")
}Add to your pubspec.yaml:
dependencies:
flowdux: ^0.3.2Add to your pubspec.yaml:
dependencies:
flowdux: ^0.3.2
flowdux_flutter: ^0.3.2data class CounterState(val count: Int = 0) : State
sealed class CounterAction : Action {
object Increment : CounterAction()
object Decrement : CounterAction()
data class Add(val value: Int) : CounterAction()
}val counterReducer = buildReducer<CounterState, CounterAction> {
on<CounterAction.Increment> { state, _ ->
state.copy(count = state.count + 1)
}
on<CounterAction.Decrement> { state, _ ->
state.copy(count = state.count - 1)
}
on<CounterAction.Add> { state, action ->
state.copy(count = state.count + action.value)
}
}class LoggingMiddleware : Middleware<CounterState, CounterAction> {
override val processors = buildProcessors {
on<CounterAction.Increment> { state, action ->
println("Incrementing from ${state.count}")
emit(action)
}
}
}class CounterErrorProcessor : ErrorProcessor<CounterAction> {
override fun process(throwable: Throwable): Flow<CounterAction> = flow {
println("Error: ${throwable.message}")
}
}val store = createStore(
initialState = CounterState(),
reducer = counterReducer,
middlewares = listOf(LoggingMiddleware()),
errorProcessor = CounterErrorProcessor(),
scope = viewModelScope
)
// Observe state
store.state.collect { state ->
println("Current count: ${state.count}")
}
// Dispatch actions
store.dispatch(CounterAction.Increment)
store.dispatch(CounterAction.Add(10))Always call close() when the store is no longer needed to release resources:
// In ViewModel
override fun onCleared() {
store.close()
super.onCleared()
}isClosed Property:
Check isClosed before dispatching if there's a possibility the store may be closed:
if (!store.isClosed) {
store.dispatch(action)
}Note: Dispatching after close() is logged via StoreLogger.onDispatchAfterClose() and may indicate a bug in your application.
| Topic | Description |
|---|---|
| Architecture | Store pipeline, middleware chain, action flow |
| Execution Strategies | takeLatest, debounce, throttle, retry, groups, chaining |
| Remote (WebSocket) | Client-server state sync, authentication, server patterns |
| Time Travel | Undo/redo, state history, branching |
| Sample Apps | How to run each sample |
| Dart/Flutter | Dart API, Flutter widgets, stream integration |
FlowDux 1.17.0 is built with Kotlin 2.2.10. For best compatibility, use the same Kotlin version in your project:
plugins {
kotlin("multiplatform") version "2.2.10"
kotlin("plugin.serialization") version "2.2.10" // if using remote modules
}Using a different Kotlin version may cause compilation errors, especially on iOS and JS targets.
When using flowdux-remote modules with kotlinx.serialization, use version 1.7.3 or compatible:
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")| Platform | Status |
|---|---|
| JVM | ✅ |
| iOS | ✅ |
| JS | ✅ |
| WASM | ❌ (Ktor client not available) |
| Platform | Status | Sample |
|---|---|---|
| JVM | ✅ | kotlin/samples/jvm |
| JVM (Remote/WebSocket) | ✅ | kotlin/samples/remote-chat |
| Android | ✅ |
kotlin/samples/android, kotlin/samples/shared/androidApp
|
| iOS | ✅ | kotlin/samples/shared/iosApp |
| JavaScript | ✅ | kotlin/samples/web |
| WebAssembly | ✅ | kotlin/samples/wasm |
| Platform | Status | Sample |
|---|---|---|
| Dart | ✅ | dart/flowdux |
| Flutter | ✅ | dart/flowdux_flutter |
Copyright 2024 Flowdux Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.