@keel-ai/router
v0.1.3
Published
File-based routing for Keel React Native apps. App Router-style — uses an `app/` directory with _layout.tsx, route groups, parallel routes. Sits on top of react-navigation 7.x.
Readme
@keel-ai/router
File-based routing for Keel React Native apps. App Router-style — same conventions as Next.js / Expo Router, adapted for mobile.
Quick start
// App.tsx — the host wires the route tree into navigation once.
import { NavigationContainer } from '@react-navigation/native';
import { RouterRoot, loadRoutes } from '@keel-ai/router';
const routes = loadRoutes(require.context('./app', true, /\.(tsx|ts)$/));
export default function App() {
return (
<NavigationContainer>
<RouterRoot routes={routes} />
</NavigationContainer>
);
}// app/_layout.tsx — declares the navigator for everything under app/.
import { Stack } from '@keel-ai/router';
export default function RootLayout() {
return <Stack />; // or <Tabs />, or <Slot /> for a pass-through layout
}RouterRoot mounts the parsed tree and provides it to the navigators and to
useRouter() (so hrefs resolve to screens + params). The host owns the
NavigationContainer, exactly like any react-navigation app.
// app/index.tsx — renders at "/"
import { Text } from 'react-native';
import { useRouter } from '@keel-ai/router';
export default function Home() {
const router = useRouter();
return <Text onPress={() => router.push('/about')}>Go about</Text>;
}// app/posts/[id].tsx — renders at "/posts/:id"
import { useLocalSearchParams } from '@keel-ai/router';
export default function Post() {
const { id } = useLocalSearchParams<{ id: string }>();
return <Text>Post {id}</Text>;
}Conventions
| Filesystem | URL |
|----------------------------|------------------|
| app/index.tsx | / |
| app/about.tsx | /about |
| app/posts/index.tsx | /posts |
| app/posts/[id].tsx | /posts/:id |
| app/posts/[id]/edit.tsx | /posts/:id/edit|
| app/(auth)/sign-in.tsx | /sign-in (group hidden from URL) |
_layout.tsx files wrap all routes under their directory. The root
app/_layout.tsx is the navigator entrypoint.
Next: metro plugin (build-time routes)
Today the route tree is walked at runtime via require.context(). A future
metro plugin (lives in keel/cloud/build-image/) will emit a static
__routes__.js virtual module + generated TypeScript types — faster cold
start + typed router.push().
Known limits (runtime path)
- Dynamic params bind to the deepest matched screen
(
/posts/42→[id].tsxgets{ id: "42" }). A dynamic value shared by an intermediate screen and a deeper one (/posts/42/edit) reaches the leaf; the intermediate reads it via its own route. replace()is a true stack replace only for a top-level target; a target inside a nested navigator falls back tonavigate().
See keel/docs/architecture.md for the broader 5-layer model @keel-ai/router fits into.
