diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3b90c01aaba..69d4ee6307f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,9 @@
 
 ## 0.12.15
 
+* `Coroutines`:
+    * Add `Flow` extensions `flatMap` and `flatten`
+
 ## 0.12.14
 
 * `Versions`:
diff --git a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/FlowFlatten.kt b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/FlowFlatten.kt
new file mode 100644
index 00000000000..095ebd3573d
--- /dev/null
+++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/FlowFlatten.kt
@@ -0,0 +1,31 @@
+package dev.inmo.micro_utils.coroutines
+
+import kotlinx.coroutines.flow.*
+
+inline fun <T, R> Flow<Flow<T>>.flatMap(
+    crossinline mapper: suspend (T) -> R
+) = flow {
+    collect {
+        it.collect {
+            emit(mapper(it))
+        }
+    }
+}
+
+inline fun <T, R> Flow<Iterable<T>>.flatMap(
+    crossinline mapper: suspend (T) -> R
+) = map {
+    it.asFlow()
+}.flatMap(mapper)
+
+inline fun <T, R> Flow<Flow<T>>.flatMapNotNull(
+    crossinline mapper: suspend (T) -> R
+) = flatMap(mapper).filterNot { it == null }
+
+inline fun <T, R> Flow<Iterable<T>>.flatMapNotNull(
+    crossinline mapper: suspend (T) -> R
+) = flatMap(mapper).filterNot { it == null }
+
+fun <T> Flow<Iterable<T>>.flatten() = flatMap { it }
+
+fun <T> Flow<Flow<T>>.flatten() = flatMap { it }