Routeit
⚡ Quick Reference
Package: @vielzeug/routeit · Category: Routing
Key exports: createRouter, createBrowserHistory, createMemoryHistory, redirectTo
When to use: Client-side routing with typed params, async data loading, middleware, guards, and View Transitions API support.
Routeit is a lightweight, framework-agnostic client-side router built around a declarative route table. Define routes once, then navigate, resolve, load route data, and build links by route name.
Installation
sh
pnpm add @vielzeug/routeitsh
npm install @vielzeug/routeitsh
yarn add @vielzeug/routeitQuick Start
ts
import { createRouter } from '@vielzeug/routeit';
const router = createRouter({
routes: {
home: {
path: '/',
handler: () => renderHome(),
},
dashboard: {
path: '/dashboard',
children: {
index: {
index: true,
handler: () => renderDashboardHome(),
},
settings: {
path: 'settings',
data: async () => fetchSettings(),
handler: ({ data }) => renderSettings(data),
},
},
},
notFound: {
path: '*',
handler: () => renderNotFound(),
},
},
});
await router.navigate({ name: 'dashboard.settings' });Why Routeit?
Managing navigation by hand usually means duplicated path checks, manual popstate listeners, and scattered history writes. Routeit keeps the routing model in one place and makes route names the source of truth.
ts
const routes = {
home: { path: '/', handler: () => renderHome() },
dashboard: {
path: '/dashboard',
children: {
index: { index: true, handler: () => renderDashboardHome() },
settings: { path: 'settings', handler: () => renderSettings() },
},
},
notFound: { path: '*', handler: () => renderNotFound() },
};
const router = createRouter({ routes });| Feature | Routeit | page.js | Navigo |
|---|---|---|---|
| Bundle size | 4.1 KB | ~1 kB | ~5 kB |
| History mode | ✅ | ✅ | ✅ |
| Memory history (tests / non-browser) | ✅ | ❌ | ❌ |
| Typed path params | ✅ | ❌ | ❌ |
| Named navigation | ✅ | ❌ | Partial |
| Middleware | ✅ | ✅ | ✅ |
| Data loaders with AbortSignal | ✅ | ❌ | ❌ |
| Lazy route loading | ✅ | ❌ | ❌ |
| Declarative redirects | ✅ | ❌ | ❌ |
| Search param validation | ✅ | ❌ | ❌ |
| Error in state | ✅ | ❌ | ❌ |
| History state in context | ✅ | ❌ | ❌ |
| Leave guards | ✅ | ❌ | ❌ |
| Route prefetching | ✅ | ❌ | ❌ |
| Scroll restoration | ✅ | ❌ | ❌ |
| View Transition API | ✅ | ❌ | ❌ |
| Zero dependencies | ✅ | ✅ | ✅ |
Features
- One declarative route table
- Nested routes with compound names like
dashboard.settings - Lazy-load route modules on first navigation
- Named-route-first navigation, URL building, and active-route detection
- Middleware for guards, analytics, and error boundaries
- Per-route
data()loaders with abort signals - Typed and coercible search params via
coerceSearch - Leave guards to block navigation from dirty forms
- Hover-prefetch via
router.preload() - Scroll restoration via the
scrolloption - History entry state readable as
ctx.historyState - Errors from data loaders exposed on
router.state.error - Memory history for tests and controlled non-browser environments
- Named-route-first
navigate(),url(), andisActive() - Route-scoped
data()loaders for leaf and layout data - Wildcard routes handle not-found cases
- Middleware handles guards, analytics, and error boundaries
navigate()handles both named routes and raw path targets
Feature Highlights
- Nested routes with
childrenandindex - Typed path params with proper inference
- Middleware at global and route scope
- Abortable route data with
data() - Metadata exposed through
router.state.matches.at(-1)?.meta - Immutable state snapshots through
router.state - Matched branch state through
router.state.matches - Base-path support for app subdirectories
- Same-URL deduplication with optional
{ force: true } - Resolve without navigation via
router.resolve() - Pluggable history drivers with browser-history default
- View transitions when the browser supports them
Compatibility
| Environment | Support |
|---|---|
| Browser | ✅ |
| Node.js | ❌ |
| SSR | ❌ |
| Deno | ❌ |
Prerequisites
- Browser runtime with the History API
- Server rewrites for deep-link support in SPAs
- Route table defined before router startup