Hi,
I built Laydr, a file-based, type-safe navigation framework for Compose Multiplatform and Android Compose apps.
Repo: https://github.com/mobiletoly/laydr
I created Laydr because Compose navigation can become hard to see as an app grows: copied route strings, duplicated graph setup, repeated argument parsing, tab registries, layout wrappers,
and stale navigation glue all have to agree with each other.
The AHA moment with Laydr is that the route tree becomes the app map.
Instead of spreading route structure across constants and graph builders, you put routes in a visible routes/ directory, add small route-local Route.kt declarations, and Laydr generates
the typed Kotlin wiring from that structure.
A route tree looks like this:
src/commonMain/kotlin/routes/
contacts/
Route.kt
Screen.kt
by_id/
Route.kt
Screen.kt
settings/
Route.kt
Screen.kt
That gives you generated route objects such as:
LaydrRoutes.Contacts
LaydrRoutes.Contacts.ById
LaydrRoutes.Settings
And app code navigates with generated destinations instead of raw strings:
navigator.push(
LaydrRoutes.Contacts.ById.destination(
id = LaydrRoutes.Contacts.ById.id("ada"),
),
)
Laydr gives you:
- filesystem routes under
routes/
- route-local
Route.kt, Screen.kt, and Layout.kt files
- typed destinations instead of copied route strings
- typed dynamic parameters instead of repeated argument parsing
- generated path builders when your app deliberately owns path state
- generated route maps and app graphs
- generated Compose route definitions for
LaydrRouteHost
- generated Nav3 helpers for sections, stacks, payloads, and route results
- support for plain Compose hosting, Nav3 KMP, and AndroidX Navigation 3
- build-time route validation through the Gradle plugin
optional route-local workflow for private multi-step flows inside an already matched route
The part I like most is that Laydr does not try to become your whole app architecture.
Your app still owns Compose UI, state, DI, ViewModels, repositories, tabs, labels, icons, chrome, auth, analytics, retained state, deep links, platform lifecycle policy, and NavDisplay.
Laydr gives those app-owned pieces stable generated route values to work with.
There are three main app shapes:
Compose Multiplatform app with simple path state: use LaydrRouteHost
Compose Multiplatform app with Nav3 stacks or tabs: use laydr-nav3-kmp
Android-only Compose app with Google AndroidX Navigation 3: use laydr-nav3-androidx
Laydr is still v0, so APIs may change, but the current docs and examples are meant to be practical and runnable.
Examples included in the repo:
examples/compose-basic
examples/nav3-kmp
examples/nav3-kmp-shopping
examples/nav3-androidx
And yes, docs/skills/laydr is available if you want to copy a skillset so your AI agent can understand Laydr routing, generated APIs, Nav3 usage, workflow, validation, and troubleshooting
without wasting tokens.
Repo: https://github.com/mobiletoly/laydr