diff --git a/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StateHandlerHolder.kt b/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StateHandlerHolder.kt
index f429ee2..dc2a58b 100644
--- a/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StateHandlerHolder.kt
+++ b/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StateHandlerHolder.kt
@@ -2,14 +2,14 @@ package dev.inmo.tgbotapi.libraries.fsm.core
 
 import kotlin.reflect.KClass
 
-class StateHandlerHolder<I : State, O : State>(
+class StateHandlerHolder<I : State>(
     private val inputKlass: KClass<I>,
     private val strict: Boolean = false,
-    private val delegateTo: StatesHandler<I, O>
-) : StatesHandler<State, O> {
+    private val delegateTo: StatesHandler<I>
+) : StatesHandler<State> {
     fun checkHandleable(state: State) = state::class == inputKlass || (!strict && inputKlass.isInstance(state))
 
-    override suspend fun handleState(state: State): O? {
-        return delegateTo.handleState(state as I)
+    override suspend fun StatesMachine.handleState(state: State): State? {
+        return delegateTo.run { handleState(state as I) }
     }
 }
diff --git a/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StatesHandler.kt b/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StatesHandler.kt
index 4996e5e..f07afbd 100644
--- a/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StatesHandler.kt
+++ b/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StatesHandler.kt
@@ -1,5 +1,5 @@
 package dev.inmo.tgbotapi.libraries.fsm.core
 
-fun interface StatesHandler<I : State, O : State> {
-    suspend fun handleState(state: I): O?
+fun interface StatesHandler<I : State> {
+    suspend fun StatesMachine.handleState(state: I): State?
 }
diff --git a/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StatesMachine.kt b/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StatesMachine.kt
index 6ad550f..5c64ef8 100644
--- a/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StatesMachine.kt
+++ b/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StatesMachine.kt
@@ -4,26 +4,24 @@ import dev.inmo.micro_utils.coroutines.*
 import kotlinx.coroutines.*
 import kotlinx.coroutines.flow.asFlow
 
-private suspend fun <I : State, O : State> launchStateHandling(
+private suspend fun <I : State> StatesMachine.launchStateHandling(
     state: State,
-    handlers: List<StateHandlerHolder<out I, out O>>
-): O? {
-    return handlers.firstOrNull { it.checkHandleable(state) } ?.handleState(
-        state
-    )
+    handlers: List<StateHandlerHolder<out I>>
+): State? {
+    return handlers.firstOrNull { it.checkHandleable(state) } ?.run {
+        handleState(state)
+    }
 }
 
-class StatesMachine<T : State, I : T, O : T>(
-    private val statesManager: StatesManager<T>,
-    private val handlers: List<StateHandlerHolder<out I, out O>>
-) : StatesHandler<T, O> {
-    override suspend fun handleState(state: T): O? {
-        return launchStateHandling(state, handlers)
-    }
+class StatesMachine (
+    private val statesManager: StatesManager,
+    private val handlers: List<StateHandlerHolder<*>>
+) : StatesHandler<State> {
+    override suspend fun StatesMachine.handleState(state: State): State? = launchStateHandling(state, handlers)
 
     fun start(scope: CoroutineScope): Job = scope.launchSafelyWithoutExceptions {
-        val statePerformer: suspend (T) -> Unit = { state: T ->
-            val newState = handleState(state)
+        val statePerformer: suspend (State) -> Unit = { state: State ->
+            val newState = launchStateHandling(state, handlers)
             if (newState != null) {
                 statesManager.update(state, newState)
             } else {
@@ -41,4 +39,8 @@ class StatesMachine<T : State, I : T, O : T>(
             launch { statePerformer(it) }
         }
     }
+
+    suspend fun startChain(state: State) {
+        statesManager.startChain(state)
+    }
 }
diff --git a/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StatesManager.kt b/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StatesManager.kt
index 59572df..023592b 100644
--- a/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StatesManager.kt
+++ b/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/StatesManager.kt
@@ -4,30 +4,30 @@ import kotlinx.coroutines.flow.*
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
 
-interface StatesManager<T : State> {
-    val onChainStateUpdated: Flow<Pair<T, T>>
-    val onStartChain: Flow<T>
-    val onEndChain: Flow<T>
+interface StatesManager {
+    val onChainStateUpdated: Flow<Pair<State, State>>
+    val onStartChain: Flow<State>
+    val onEndChain: Flow<State>
 
 
     /**
      * Must set current set using [State.context]
      */
-    suspend fun update(old: T, new: T)
+    suspend fun update(old: State, new: State)
 
     /**
      * Starts chain with [state] as first [State]. May returns false in case of [State.context] of [state] is already
      * busy by the other [State]
      */
-    suspend fun startChain(state: T)
+    suspend fun startChain(state: State)
 
     /**
      * Ends chain with context from [state]. In case when [State.context] of [state] is absent, [state] should be just
      * ignored
      */
-    suspend fun endChain(state: T)
+    suspend fun endChain(state: State)
 
-    suspend fun getActiveStates(): List<T>
+    suspend fun getActiveStates(): List<State>
 }
 
 /**
@@ -35,20 +35,20 @@ interface StatesManager<T : State> {
  * key. In case when this callback will returns true, the state placed on [State.context] of new will be replaced by
  * new state by using [endChain] with that state
  */
-class InMemoryStatesManager<T : State>(
-    private val onContextsConflictResolver: suspend (old: T, new: T, currentNew: T) -> Boolean = { _, _, _ -> true }
-) : StatesManager<T> {
-    private val _onChainStateUpdated = MutableSharedFlow<Pair<T, T>>(0)
-    override val onChainStateUpdated: Flow<Pair<T, T>> = _onChainStateUpdated.asSharedFlow()
-    private val _onStartChain = MutableSharedFlow<T>(0)
-    override val onStartChain: Flow<T> = _onStartChain.asSharedFlow()
-    private val _onEndChain = MutableSharedFlow<T>(0)
-    override val onEndChain: Flow<T> = _onEndChain.asSharedFlow()
+class InMemoryStatesManager(
+    private val onContextsConflictResolver: suspend (old: State, new: State, currentNew: State) -> Boolean = { _, _, _ -> true }
+) : StatesManager {
+    private val _onChainStateUpdated = MutableSharedFlow<Pair<State, State>>(0)
+    override val onChainStateUpdated: Flow<Pair<State, State>> = _onChainStateUpdated.asSharedFlow()
+    private val _onStartChain = MutableSharedFlow<State>(0)
+    override val onStartChain: Flow<State> = _onStartChain.asSharedFlow()
+    private val _onEndChain = MutableSharedFlow<State>(0)
+    override val onEndChain: Flow<State> = _onEndChain.asSharedFlow()
 
-    private val contextsToStates = mutableMapOf<Any, T>()
+    private val contextsToStates = mutableMapOf<Any, State>()
     private val mapMutex = Mutex()
 
-    override suspend fun update(old: T, new: T) = mapMutex.withLock {
+    override suspend fun update(old: State, new: State) = mapMutex.withLock {
         when {
             contextsToStates[old.context] != old -> return@withLock
             old.context == new.context || !contextsToStates.containsKey(new.context) -> {
@@ -67,26 +67,26 @@ class InMemoryStatesManager<T : State>(
         }
     }
 
-    override suspend fun startChain(state: T) = mapMutex.withLock {
+    override suspend fun startChain(state: State) = mapMutex.withLock {
         if (!contextsToStates.containsKey(state.context)) {
             contextsToStates[state.context] = state
             _onStartChain.emit(state)
         }
     }
 
-    private suspend fun endChainWithoutLock(state: T) {
+    private suspend fun endChainWithoutLock(state: State) {
         if (contextsToStates[state.context] == state) {
             contextsToStates.remove(state.context)
             _onEndChain.emit(state)
         }
     }
 
-    override suspend fun endChain(state: T) {
+    override suspend fun endChain(state: State) {
         mapMutex.withLock {
             endChainWithoutLock(state)
         }
     }
 
-    override suspend fun getActiveStates(): List<T> = contextsToStates.values.toList()
+    override suspend fun getActiveStates(): List<State> = contextsToStates.values.toList()
 
 }
diff --git a/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/dsl/FSMBuilder.kt b/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/dsl/FSMBuilder.kt
new file mode 100644
index 0000000..d8d6dac
--- /dev/null
+++ b/fsm/core/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/fsm/core/dsl/FSMBuilder.kt
@@ -0,0 +1,35 @@
+package dev.inmo.tgbotapi.libraries.fsm.core.dsl
+
+import dev.inmo.tgbotapi.libraries.fsm.core.*
+import kotlin.reflect.KClass
+
+class FSMBuilder(
+    var statesManager: StatesManager = InMemoryStatesManager()
+) {
+    private var states = mutableListOf<StateHandlerHolder<*>>()
+
+    fun <I : State> add(kClass: KClass<I>, handler: StatesHandler<I>) {
+        states.add(StateHandlerHolder(kClass, false, handler))
+    }
+
+    fun <I : State> addStrict(kClass: KClass<I>, handler: StatesHandler<I>) {
+        states.add(StateHandlerHolder(kClass, true, handler))
+    }
+
+    fun build() = StatesMachine(
+        statesManager,
+        states.toList()
+    )
+}
+
+inline fun <reified I : State> FSMBuilder.onStateOrSubstate(handler: StatesHandler<I>) {
+    add(I::class, handler)
+}
+
+inline fun <reified I : State> FSMBuilder.strictlyOn(handler: StatesHandler<I>) {
+    addStrict(I::class, handler)
+}
+
+fun buildFSM(
+    block: FSMBuilder.() -> Unit
+): StatesMachine = FSMBuilder().apply(block).build()
diff --git a/fsm/core/src/jvmTest/kotlin/PlayableMain.kt b/fsm/core/src/jvmTest/kotlin/PlayableMain.kt
index 70291f4..5bb1a5d 100644
--- a/fsm/core/src/jvmTest/kotlin/PlayableMain.kt
+++ b/fsm/core/src/jvmTest/kotlin/PlayableMain.kt
@@ -1,4 +1,6 @@
 import dev.inmo.tgbotapi.libraries.fsm.core.*
+import dev.inmo.tgbotapi.libraries.fsm.core.dsl.buildFSM
+import dev.inmo.tgbotapi.libraries.fsm.core.dsl.strictlyOn
 import kotlinx.coroutines.*
 import kotlin.random.Random
 import kotlin.test.Test
@@ -24,27 +26,25 @@ class PlayableMain {
                 }
             }
 
-            val statesManager = InMemoryStatesManager<TrafficLightState>()
+            val statesManager = InMemoryStatesManager()
 
-            val machine = StatesMachine(
-                statesManager,
-                listOf(
-                    StateHandlerHolder(GreenCommon::class) {
-                        delay(1000L)
-                        YellowCommon(it.context).also(::println)
-                    },
-                    StateHandlerHolder(YellowCommon::class) {
-                        delay(1000L)
-                        RedCommon(it.context).also(::println)
-                    },
-                    StateHandlerHolder(RedCommon::class) {
-                        delay(1000L)
-                        GreenCommon(it.context).also(::println)
-                    }
-                )
-            )
+            val machine = buildFSM {
+                strictlyOn<GreenCommon> {
+                    delay(1000L)
+                    YellowCommon(it.context).also(::println)
+                }
+                strictlyOn<YellowCommon> {
+                    delay(1000L)
+                    RedCommon(it.context).also(::println)
+                }
+                strictlyOn<RedCommon> {
+                    delay(1000L)
+                    GreenCommon(it.context).also(::println)
+                }
+                this.statesManager = statesManager
+            }
 
-            initialStates.forEach { statesManager.startChain(it) }
+            initialStates.forEach { machine.startChain(it) }
 
             val scope = CoroutineScope(Dispatchers.Default)
             machine.start(scope).join()