lite-trie-router
v1.0.0
Published
Ultra-light React router with O(M) trie matching, predictive preload, and useSyncExternalStore
Maintainers
Readme
lite-trie-router
Ultra-light React router (~2KB min+gzip) built for O(M) URL matching (M = path segments), predictive code-split preloading, and useSyncExternalStore history sync.
Why this router?
| Technique | Benefit |
| ----------------------- | ---------------------------------------------------------------- |
| Segment trie | Match cost grows with URL depth, not total route count |
| Shared import cache | Hover prefetch and click navigation reuse one import() promise |
| History patch | pushState / replaceState / popstate all notify React |
| Manual path split | No regex on hot path; V8-friendly string scans |
| startTransition | Route paint stays responsive during chunk resolution |
Install
npm install lite-trie-routerPeer dependency: React 18+.
Quick start
import { CustomRouter, Link, useParams, useQuery } from "lite-trie-router";
const routes = [
{ path: "/", loadFn: () => import("./pages/Home.jsx") },
{ path: "/dashboard/:userId", loadFn: () => import("./pages/Dashboard.jsx") },
];
export default function App() {
return (
<CustomRouter
routes={routes}
fallback={<div>404</div>}
loadingFallback={<div>Loading…</div>}
>
<nav>
<Link to="/dashboard/abc?tab=metrics">Dashboard</Link>
</nav>
</CustomRouter>
);
}
function DashboardPage() {
const { userId } = useParams();
const { tab } = useQuery();
return (
<h1>
{userId} — {tab}
</h1>
);
}Note: Place
<Link>inside<CustomRouter>so prefetch can access the compiled trie.
API
Components
CustomRouter—{ routes, fallback, loadingFallback?, children? }Link—{ to, prefetch?, ...anchorProps }— preloads onmouseenter,focus, andtouchstart
Hooks
useParams()— dynamic segments (:id→{ id: '42' })useQuery()— parsed query objectuseHash()— hash without#useLocation()—{ pathname, search, hash }
Imperative
import { navigate } from "lite-trie-router";
navigate("/settings", { replace: true });Low-level (testing / custom integrations)
createTrieRouter(routes)matchTrie(root, pathname, segments?)parseUrl(url)splitPath(pathname)prefetchRoute(routeKey, loadFn)clearRouteCache()
Performance tips
- Use stable
routesarray reference (or memoize) to avoid rebuilding the trie. - Keep
loadFnas() => import('./Page')— the library dedupes by routepath. - Disable prefetch on huge menus:
<Link prefetch={false} />. - Run
npm run benchlocally — reports match-only (cached segments) vs split+match. - High fanout nodes (48+ sibling routes) auto-switch to
Maplookups at compile time.
License
MIT
