Skip to content

The mental model

raku_router is five small layers. Each one is independently useful, and each is built on the one above it. You can stop at any level your app needs.

RakuRoute
RouteStack
RouteStackView
BranchedRouteStack
raku(routes: […])
data → reactive stack → a Navigator → tabs → a URL tree

A destination is an immutable object, ideally a sealed class so a switch over it is exhaustive (the compiler is your route table). No code generation.

sealed class AppRoute extends RakuRoute { const AppRoute(); }
class Home extends AppRoute { const Home(); }
class Note extends AppRoute {
const Note(this.id);
final String id;
@override
List<Object?> get props => [id]; // identity + URL building
}

2. RouteStack — a reactive list of routes

Section titled “2. RouteStack — a reactive list of routes”

The heart of raku_router: a mutable List<route> exposed as a ValueListenable. It depends only on flutter/foundation — no UI, no state-management. push, pop, replace, reset. Mutations honour guards and redirects.

3. RouteStackView — render a stack as a Navigator

Section titled “3. RouteStackView — render a stack as a Navigator”

Turns a RouteStack into a real Navigator with pages and transitions. Drop it into MaterialApp.home (or any app shell). This is all you need for an app without deep linking.

4. BranchedRouteStack — many stacks, one active

Section titled “4. BranchedRouteStack — many stacks, one active”

Tabs. Each branch owns its own RouteStack, so switching tabs preserves each one’s back history. BranchedStackView renders it (lazy, state-preserving).

5. raku(routes: […]) — a declarative URL tree

Section titled “5. raku(routes: […]) — a declarative URL tree”

The top layer ties a URL’s structure to a typed navigation stack, both ways: deep linking, browser back/forward, and address-bar sync, with no hand-written parsing. See URL ⇄ stack.