obix-core-router
v0.5.0
Published
OBIX Router - SPA navigation with scroll restoration, deep linking
Readme
obix-core-router
Previous name:
@obinexusltd/obix-core-router— OBIX packages are named without an npm scope since decision D-102 (2026-09-29); the package, its version and its exports are unchanged.
Client-side SPA routing with per-path scroll restoration and hash-based deep
linking, built on history.pushState — no framework dependency, no virtual
DOM.
The problem it owns
Client routers usually bundle three concerns that don't need to be coupled:
matching a URL to a route, remembering where the user was scrolled to when
they navigate away and back, and encoding enough state into the URL that a
link can be shared and resumed. createRouter gives you all three behind
one ObixRouter, with scroll capture keyed by path and deep-link state
serialized into the URL hash, while staying an exact-path matcher — no
pattern syntax, no route tree to learn.
Install
npm install obix-core-routerAPI
import {
createRouter,
type RouterConfig,
type ObixRouter,
type Route,
type NavigationGuard,
type NavigationResult,
type DeepLinkConfig,
type ScrollRestorationMode,
} from "obix-core-router";| Export | Description |
|--------|-------------|
| createRouter(config: RouterConfig) | Factory. Returns an ObixRouter bound to config.routes. |
| navigate(path, state?) | Runs guards, updates the current route, pushes a new history entry, and restores/resets scroll. Resolves to a NavigationResult. See docs/navigation-guards.md. |
| back() / forward() | Thin wrappers over history.back()/history.forward(). No NavigationResult — the outcome arrives via the popstate listener, not a return value. |
| restoreScroll(position?) | With a position, scrolls there immediately and overwrites the saved position for the current path. Without one, replays whatever restoration logic would normally run. See docs/scroll-restoration.md. |
| registerGuard(guard) | Appends a NavigationGuard to the list navigate() runs through. |
| getDeepLink() | Current path, plus a serialized-state hash when deep linking is enabled. See docs/deep-linking.md. |
| getCurrentRoute() | The Route matching the current path, or a synthetic not-found route. See docs/routing-and-path-matching.md. |
See docs/api-reference.md for the full type reference.
Example
import { createRouter } from "obix-core-router";
const router = createRouter({
routes: [
{ path: "/", name: "home" },
{ path: "/feed", name: "feed" },
],
baseUrl: "/app",
scrollRestoration: "auto",
deepLink: { enabled: true },
guards: [
{
beforeNavigate: (to) => to.name !== "feed" || confirm("Leave the editor?"),
afterNavigate: (to) => document.title = `OBIX — ${to.name}`,
},
],
});
const result = await router.navigate("/feed", { page: 3, filter: "latest" });
if (result.success) {
console.log(router.getDeepLink()); // "/app/feed#%7B%22page%22%3A3...%7D"
}Docs
- docs/api-reference.md — full type and method reference
- docs/routing-and-path-matching.md —
Route, exact-path matching, the syntheticnot-foundroute - docs/navigation-guards.md —
NavigationGuardordering, short-circuiting, and what guards don't cover - docs/scroll-restoration.md — how
scrollRestorationmodes interact with nativehistory.scrollRestoration - docs/deep-linking.md —
DeepLinkConfig, hash serialization, and state rehydration onpopstate
Boundary
- Exact-string path matching only.
routesByPathis a plainMap<string, Route>built once at construction fromconfig.routes. There is no dynamic-segment syntax (/users/:id), no wildcards, and no query string parsing — a navigated path either matches a registered route exactly (after normalization) or resolves to a synthetic{ name: "not-found", metadata: { missingRoute: true } }route. Route.childrenandRoute.componentare typed but unused. Nested routes are not flattened or matched recursively — only the top-level entries inconfig.routesare indexed.componentcarries no rendering behavior; this package does no DOM mounting.- Guards don't run on browser Back/Forward.
beforeNavigate/afterNavigateonly fire insidenavigate(). Thepopstatelistener (native back/forward, or history entries changing outside this router) updatescurrentPath/currentState/scroll directly, bypassing guards entirely. navigate()always pushes, never replaces. Every call ishistory.pushState; there's nonavigate(path, state, { replace: true })option.- An
afterNavigateguard that throws rejectsnavigate()'s promise after the navigation already took effect — URL,currentPath, and scroll are already updated by the timeafterNavigatehooks run, so a caller catching the rejection should not assume the navigation was rolled back.
MIT — OBINexus Computing
Installation
npm install obix-core-routerAPI surface
obix-core-router— 1 value export:createRouter- Type declarations:
./dist/index.d.ts(and a declaration next to every JS entry point).
Architecture role
obix-core-router is a public building block: the umbrella obix depends on it and re-exports its stable API, so applications normally reach it through obix; it can also be installed on its own.
The architecture of OBIX — the package families and which packages are public API — is indexed in the umbrella: docs/architecture.md.
Package relationships
- Depends on (OBIX): no other OBIX package.
- Used by (OBIX):
obix.
Testing
- 1 test file ships in the npm package (
__tests__/): the evidence of the package's contract, published so that its verification can be inspected — not runtime code (no entry point reaches it). - Standalone: 1 of 1 — it reads nothing outside the package.
- Run them with
npm test(vitest run) in the OBIX monorepo, which provides the test tooling (Node's test runner, Vitest, TypeScript) and the harness.
Documentation
- docs/api-reference.md
- docs/deep-linking.md
- docs/navigation-guards.md
- docs/routing-and-path-matching.md
- docs/scroll-restoration.md
- CHANGELOG.md
- The OBIX architecture index: obix/docs/architecture.md
Repository
- https://github.com/obinexus/obix-core-router —
[email protected]:obinexus/obix-core-router.git - Issues: https://github.com/obinexus/obix-core-router/issues
- The repository is a clean export of the package from the OBIX monorepo. Its lineage — the sources it was recovered from and its earlier names — is
PROVENANCE.json, shipped in this package; the repository's copy also records the monorepo commit it was exported from.
License
MIT — see LICENSE.
