diff --git a/integration/voyager/common/src/dev/programadorthi/routing/voyager/VoyagerRoutingBuilder.kt b/integration/voyager/common/src/dev/programadorthi/routing/voyager/VoyagerRoutingBuilder.kt
index b747d49..dc676d5 100644
--- a/integration/voyager/common/src/dev/programadorthi/routing/voyager/VoyagerRoutingBuilder.kt
+++ b/integration/voyager/common/src/dev/programadorthi/routing/voyager/VoyagerRoutingBuilder.kt
@@ -30,6 +30,19 @@ public fun Route.screen(
     body: suspend PipelineContext<Unit, ApplicationCall>.() -> Screen,
 ): Route = route(path = path, name = name, method = method) { screen(body) }
 
+@KtorDsl
+public fun Route.screen(
+    path: Regex,
+    body: suspend PipelineContext<Unit, ApplicationCall>.() -> Screen,
+): Route = route(path = path) { screen(body) }
+
+@KtorDsl
+public fun Route.screen(
+    path: Regex,
+    method: RouteMethod,
+    body: suspend PipelineContext<Unit, ApplicationCall>.() -> Screen,
+): Route = route(path = path, method = method) { screen(body) }
+
 @KtorDsl
 public fun Route.screen(body: suspend PipelineContext<Unit, ApplicationCall>.() -> Screen) {
     val routing = asRouting ?: error("Your route $this must have a parent Routing")
diff --git a/integration/voyager/common/test/dev/programadorthi/routing/voyager/Screens.kt b/integration/voyager/common/test/dev/programadorthi/routing/voyager/Screens.kt
index 2a5bf92..7491f44 100644
--- a/integration/voyager/common/test/dev/programadorthi/routing/voyager/Screens.kt
+++ b/integration/voyager/common/test/dev/programadorthi/routing/voyager/Screens.kt
@@ -60,3 +60,12 @@ internal class Screen5(@Body val user: User) : Screen {
         invoked += "/screen-with-body" to listOf(user)
     }
 }
+
+@Route(regex = "/(?<number>\\d+)")
+internal class Screen6(val number: Int) : Screen {
+
+    @Composable
+    override fun Content() {
+        invoked += "/(?<number>\\d+)" to listOf(number)
+    }
+}
diff --git a/integration/voyager/common/test/dev/programadorthi/routing/voyager/VoyagerRoutingTest.kt b/integration/voyager/common/test/dev/programadorthi/routing/voyager/VoyagerRoutingTest.kt
index 9f0b7d9..e0f8132 100644
--- a/integration/voyager/common/test/dev/programadorthi/routing/voyager/VoyagerRoutingTest.kt
+++ b/integration/voyager/common/test/dev/programadorthi/routing/voyager/VoyagerRoutingTest.kt
@@ -4,6 +4,7 @@ import cafe.adriel.voyager.navigator.CurrentScreen
 import cafe.adriel.voyager.navigator.Navigator
 import dev.programadorthi.routing.core.RouteMethod
 import dev.programadorthi.routing.core.application.ApplicationCall
+import dev.programadorthi.routing.core.application.call
 import dev.programadorthi.routing.core.application.createApplicationPlugin
 import dev.programadorthi.routing.core.application.hooks.CallFailed
 import dev.programadorthi.routing.core.call
@@ -17,12 +18,12 @@ import dev.programadorthi.routing.voyager.helper.FakeScreen
 import dev.programadorthi.routing.voyager.helper.runComposeTest
 import io.ktor.http.Parameters
 import io.ktor.http.parametersOf
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.advanceTimeBy
 import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertIs
 import kotlin.test.assertNotNull
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.advanceTimeBy
 
 @OptIn(ExperimentalCoroutinesApi::class)
 internal class VoyagerRoutingTest {
@@ -150,10 +151,10 @@ internal class VoyagerRoutingTest {
             // THEN
             assertNotNull(result)
             assertNotNull(exception)
-            assertEquals("/path", "${result?.uri}")
-            assertEquals("", "${result?.name}")
-            assertEquals(RouteMethod.Empty, result?.routeMethod)
-            assertEquals(Parameters.Empty, result?.parameters)
+            assertEquals("/path", result.uri)
+            assertEquals("", result.name)
+            assertEquals(RouteMethod.Empty, result.routeMethod)
+            assertEquals(Parameters.Empty, result.parameters)
             assertIs<IllegalStateException>(exception)
             assertEquals(
                 "Voyager needs a stack route method to work. You called a screen /path using " +
@@ -374,9 +375,9 @@ internal class VoyagerRoutingTest {
                 VoyagerRouting(
                     routing = routing,
                     initialScreen =
-                        FakeScreen().apply {
-                            content = "I am the initial screen"
-                        },
+                    FakeScreen().apply {
+                        content = "I am the initial screen"
+                    },
                 ) { nav ->
                     navigator = nav
                     CurrentScreen()
@@ -444,9 +445,9 @@ internal class VoyagerRoutingTest {
                 VoyagerRouting(
                     routing = routing,
                     initialScreen =
-                        FakeScreen().apply {
-                            content = "I am the initial screen"
-                        },
+                    FakeScreen().apply {
+                        content = "I am the initial screen"
+                    },
                 ) { nav ->
                     navigator = nav
                     CurrentScreen()
@@ -496,9 +497,9 @@ internal class VoyagerRoutingTest {
                 VoyagerRouting(
                     routing = routing,
                     initialScreen =
-                        FakeScreen().apply {
-                            content = "I am the initial screen"
-                        },
+                    FakeScreen().apply {
+                        content = "I am the initial screen"
+                    },
                 ) { nav ->
                     navigator = nav
                     CurrentScreen()
@@ -528,4 +529,71 @@ internal class VoyagerRoutingTest {
             // THEN
             assertEquals(parametersOf("key" to listOf("value")), firstPushedScreen?.parameters)
         }
+
+    @Test
+    fun shouldNavigateByRegex() =
+        runComposeTest { coroutineContext, composition, clock ->
+            // GIVEN
+            val fakeScreen = FakeScreen()
+
+            val routing =
+                routing(parentCoroutineContext = coroutineContext) {
+                    screen(path = Regex("/(?<number>\\d+)")) {
+                        fakeScreen.apply {
+                            content = "Hey, I am the called screen with number ${call.parameters["number"]}"
+                        }
+                    }
+                }
+
+            composition.setContent {
+                VoyagerRouting(
+                    routing = routing,
+                    initialScreen = FakeScreen(),
+                )
+            }
+
+            // WHEN
+            routing.push(path = "/123")
+            advanceTimeBy(99) // Ask for routing
+            clock.sendFrame(0L) // Ask for recomposition
+
+            // THEN
+            assertEquals("Hey, I am the called screen with number 123", fakeScreen.composed)
+        }
+
+    @Test
+    fun shouldNavigateByRegexWithMultipleParameters() =
+        runComposeTest { coroutineContext, composition, clock ->
+            // GIVEN
+            val fakeScreen = FakeScreen()
+
+            val routing =
+                routing(parentCoroutineContext = coroutineContext) {
+                    route(path = Regex("/(?<number>\\d+)")) {
+                        screen(path = Regex("(?<user>\\w+)/(?<login>.+)")) {
+                            fakeScreen.apply {
+                                content = "Hey, I am the called screen with ${call.parameters}"
+                            }
+                        }
+                    }
+                }
+
+            composition.setContent {
+                VoyagerRouting(
+                    routing = routing,
+                    initialScreen = FakeScreen(),
+                )
+            }
+
+            // WHEN
+            routing.push(path = "/456/qwe/rty")
+            advanceTimeBy(99) // Ask for routing
+            clock.sendFrame(0L) // Ask for recomposition
+
+            // THEN
+            assertEquals(
+                "Hey, I am the called screen with Parameters [number=[456], user=[qwe], login=[rty]]",
+                fakeScreen.composed
+            )
+        }
 }
diff --git a/integration/voyager/jvm/test/dev/programadorthi/routing/voyager/VoyagerRoutingByAnnotationsTest.kt b/integration/voyager/jvm/test/dev/programadorthi/routing/voyager/VoyagerRoutingByAnnotationsTest.kt
index a3e4708..053b159 100644
--- a/integration/voyager/jvm/test/dev/programadorthi/routing/voyager/VoyagerRoutingByAnnotationsTest.kt
+++ b/integration/voyager/jvm/test/dev/programadorthi/routing/voyager/VoyagerRoutingByAnnotationsTest.kt
@@ -151,4 +151,29 @@ internal class VoyagerRoutingByAnnotationsTest {
             assertEquals(listOf(body), invoked.remove("/screen-with-body"))
         }
 
+    @Test
+    fun shouldHandleScreenRegex() =
+        runComposeTest { coroutineContext, composition, clock ->
+            // GIVEN
+            val routing =
+                routing(parentCoroutineContext = coroutineContext) {
+                    configure()
+                }
+
+            composition.setContent {
+                VoyagerRouting(
+                    routing = routing,
+                    initialScreen = FakeScreen(),
+                )
+            }
+
+            // WHEN
+            routing.push(path = "/123")
+            advanceTimeBy(99) // Ask for routing
+            clock.sendFrame(0L) // Ask for recomposition
+
+            // THEN
+            assertEquals(listOf(123), invoked.remove("/(?<number>\\d+)"))
+        }
+
 }
diff --git a/ksp/core-processor/jvm/src/dev/programadorthi/routing/ksp/RoutingProcessor.kt b/ksp/core-processor/jvm/src/dev/programadorthi/routing/ksp/RoutingProcessor.kt
index 58327ca..988bf25 100644
--- a/ksp/core-processor/jvm/src/dev/programadorthi/routing/ksp/RoutingProcessor.kt
+++ b/ksp/core-processor/jvm/src/dev/programadorthi/routing/ksp/RoutingProcessor.kt
@@ -150,18 +150,13 @@ private class RoutingProcessor(
             "@Route having regex can't be named"
         }
 
-        val isScreen = classKind != null
         val memberName = when {
             annotations.any { it.shortName.asString() == "Composable" } -> composable
-            isScreen -> screen
+            classKind != null -> screen
             else -> handle
         }
 
         if (isRegexRoute) {
-            check(!isScreen) {
-                // TODO: Add regex support to composable handle
-                "$qualifiedName has @Route(regex = ...) that cannot be applied to @Composable or Voyager Screen"
-            }
             if (routeAnnotation.method.isBlank()) {
                 configureSpec
                     .beginControlFlow(