npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@reliance/simple-router

v1.0.1

Published

A lightweight, plug-and-play React routing system with TypeScript support

Downloads

9

Readme

@reliance/simple-router

A lightweight, plug-and-play React routing system with TypeScript support. Designed for microfrontends and applications that need flexible routing without the complexity of larger routing libraries.

Features

  • 🚀 Lightweight: Minimal bundle size with zero dependencies
  • 🔧 Framework Agnostic Core: Core utilities work without React
  • 📦 Plug and Play: Easy integration with existing applications
  • 🎯 TypeScript First: Full TypeScript support with comprehensive types
  • 🔄 Route Parameters: Dynamic route parameters with type safety
  • 🔍 Query Parameters: Built-in query parameter handling
  • 🏗️ Nested Routes: Support for complex nested routing structures
  • 🛡️ Route Guards: Authentication and authorization guards
  • 📱 SSR Compatible: Works with server-side rendering
  • 🎨 Flexible: Use with any UI framework or component library

Installation

npm install @reliance/simple-router
# or
yarn add @reliance/simple-router

Quick Start

import React from "react";
import { Router, Link, useRouteParams } from "@reliance/simple-router";

// Define your route components
const Home = () => <div>Home Page</div>;
const About = () => <div>About Page</div>;
const User = () => {
  const params = useRouteParams<{ id: string }>();
  return <div>User: {params.id}</div>;
};

// Define your routes
const routes = [
  { path: "/", component: Home, exact: true },
  { path: "/about", component: About },
  { path: "/user/:id", component: User },
];

// Use the router
function App() {
  return <Router routes={routes} />;
}

// Navigation example in a component
function Navigation() {
  return (
    <nav>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/user/123">User 123</Link>
    </nav>
  );
}

Core Concepts

Route Configuration

import { RouteConfig } from "@reliance/simple-router";

const routes: RouteConfig[] = [
  {
    path: "/",
    component: HomePage,
    exact: true,
    title: "Home",
  },
  {
    path: "/products",
    component: ProductsLayout,
    children: [
      { path: "", component: ProductsList, exact: true },
      { path: "/:id", component: ProductDetail },
      { path: "/new", component: CreateProduct },
    ],
  },
];

Route Parameters

Access route parameters using the useRouteParams hook:

import { useRouteParams } from "@reliance/simple-router";

function ProductDetail() {
  const params = useRouteParams<{ id: string }>();
  return <div>Product ID: {params.id}</div>;
}

Or use the combined useParams hook to get both route and query parameters:

import { useParams } from "@reliance/simple-router";

function ProductDetail() {
  const params = useParams<{ id: string; sort?: string }>();
  return (
    <div>
      <div>Product ID: {params.id}</div>
      <div>Sort: {params.sort}</div>
    </div>
  );
}

Query Parameters

import { useQueryParams } from "@reliance/simple-router";

function ProductsList() {
  const { queryParams, setQueryParams } = useQueryParams();

  const search = queryParams.search || "";
  const page = Number(queryParams.page) || 1;

  return (
    <div>
      <input
        value={search}
        onChange={(e) => setQueryParams({ search: e.target.value, page: "1" })}
      />
      <div>Page: {page}</div>
    </div>
  );
}

Route Guards

Protect routes with authentication and authorization guards:

import {
  createAuthGuard,
  createRoleGuard,
  combineGuards,
} from "@reliance/simple-router";

const authGuard = createAuthGuard(
  () => !!localStorage.getItem("token"),
  "/login"
);

const adminGuard = createRoleGuard(
  (roles) => roles.includes("admin"),
  ["admin"],
  "/unauthorized"
);

const routes = [
  {
    path: "/dashboard",
    component: Dashboard,
    guards: [authGuard],
  },
  {
    path: "/admin",
    component: AdminPanel,
    guards: [combineGuards(authGuard, adminGuard)],
  },
];

Advanced Usage

Programmatic Navigation

import { useNavigate } from "@reliance/simple-router";

function MyComponent() {
  const { navigate, back, forward, replace } = useNavigate();

  const handleNavigation = () => {
    // Navigate to a new route
    navigate("/dashboard");

    // Navigate with query parameters
    navigate("/products", { queryParams: { category: "electronics" } });

    // Replace current route (no history entry)
    replace("/login");

    // Go back/forward in history
    back();
    forward();
  };
}

Pagination Hook

import { usePagination } from "@reliance/simple-router";

function DataTable() {
  const { page, limit, setPage, nextPage, previousPage } = usePagination(1, 20);

  return (
    <div>
      <div>Page {page}</div>
      <button onClick={previousPage} disabled={page === 1}>
        Previous
      </button>
      <button onClick={nextPage}>Next</button>
    </div>
  );
}

Filters Hook

Manage filter state synchronized with URL query parameters:

import { useFilters } from "@reliance/simple-router";

function ProductFilters() {
  const { filters, setFilter, resetFilters } = useFilters({
    category: "",
    minPrice: 0,
    maxPrice: 1000,
  });

  return (
    <div>
      <select
        value={filters.category}
        onChange={(e) => setFilter("category", e.target.value)}
      >
        <option value="">All Categories</option>
        <option value="electronics">Electronics</option>
      </select>
      <button onClick={resetFilters}>Reset</button>
    </div>
  );
}

URL State Management

import { useUrlState } from "@reliance/simple-router";

function SearchForm() {
  const [searchTerm, setSearchTerm] = useUrlState("search", "");

  return (
    <input value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} />
  );
}

Building URLs with Route Parameters

import { buildRoutePath } from "@reliance/simple-router";

// Build URLs with route parameters
const userUrl = buildRoutePath("/users/:id", { id: "123" });
// Result: "/users/123"

const postUrl = buildRoutePath("/users/:userId/posts/:postId", {
  userId: "123",
  postId: "456",
});
// Result: "/users/123/posts/456"

Framework Agnostic Core

The core utilities can be used without React:

import {
  parseQueryParams,
  buildRoutePath,
  RouteMatcher,
  Navigator,
} from "@reliance/simple-router";

// Parse query parameters
const params = parseQueryParams("?search=react&page=2");
// { search: 'react', page: '2' }

// Build route with parameters
const path = buildRoutePath("/users/:id/posts/:postId", {
  id: "123",
  postId: "456",
});
// '/users/123/posts/456'

// Match routes
const matcher = new RouteMatcher([{ path: "/users/:id", component: null }]);
const match = matcher.match("/users/123");
// { route: {...}, params: { id: '123' }, ... }

// Create a navigator for programmatic navigation
const navigator = new Navigator();
navigator.navigate("/dashboard");

Patterns & Best Practices

Centralized Route Configuration

Create a dedicated file for your application routes:

// routes.ts
import { RouteConfig } from "@reliance/simple-router";
import {
  HomePage,
  UserPage,
  ProductPage,
  ProductList,
  ProductDetail,
} from "./pages";
import { authGuard } from "./guards";

export const appRoutes: RouteConfig[] = [
  {
    path: "/",
    component: HomePage,
    exact: true,
    title: "Home - My App",
  },
  {
    path: "/users/:id",
    component: UserPage,
    title: "User Profile - My App",
    guards: [authGuard],
  },
  {
    path: "/products",
    component: ProductPage,
    children: [
      { path: "", component: ProductList, exact: true },
      { path: "/:id", component: ProductDetail },
    ],
  },
];

Microfrontend Integration

For microfrontend architectures, each microfrontend can have its own routes that are combined at the shell level:

// Wallet microfrontend routes
export const walletRoutes: RouteConfig[] = [
  { path: "/wallet", component: WalletDashboard, exact: true },
  { path: "/wallet/transactions", component: Transactions },
];

// Payment microfrontend routes
export const paymentRoutes: RouteConfig[] = [
  { path: "/payments", component: PaymentDashboard, exact: true },
  { path: "/payments/history", component: PaymentHistory },
];

// Shell app combines all routes
import { Router } from "@reliance/simple-router";

function App() {
  const allRoutes = [...walletRoutes, ...paymentRoutes];
  return <Router routes={allRoutes} />;
}

Using Base Path for Microfrontends

Configure a base path for each microfrontend:

// In each microfrontend
function WalletApp() {
  return <Router routes={walletRoutes} basePath="/wallet-ms" />;
}

TypeScript Support

Full TypeScript support with comprehensive type definitions:

import { useRouteParams, useQueryParams } from "@reliance/simple-router";
import type { RouteParams, QueryParams } from "@reliance/simple-router";

interface UserParams extends RouteParams {
  id: string;
}

interface UserQuery extends QueryParams {
  tab?: string;
  section?: string;
}

function UserProfile() {
  const params = useRouteParams<UserParams>();
  const { queryParams } = useQueryParams();

  // params.id is typed as string
  // queryParams.tab is typed as string | string[] | undefined
  const tab = queryParams.tab as string | undefined;
}

API Reference

Components

Router

Main router component that manages navigation and renders matched routes.

Props:

  • routes: RouteConfig[] - Array of route configurations
  • basePath?: string - Base path for all routes (default: "")
  • hashMode?: boolean - Use hash-based routing (default: false)
  • caseSensitive?: boolean - Case-sensitive route matching (default: false)
  • onNotFound?: React.ComponentType - Custom 404 component
  • onLoading?: React.ComponentType - Custom loading component

Link

Navigation link component.

Props:

  • to: string - Target path
  • replace?: boolean - Replace current history entry
  • className?: string - CSS class
  • activeClassName?: string - CSS class when link is active
  • exact?: boolean - Exact path matching for active state
  • onClick?: () => void - Click handler

Hooks

useRoute()

Get current route match information.

Returns: RouteMatch | null

useRouteParams<T>()

Get route parameters (e.g., /users/:id).

Returns: T extends RouteParams

useParams<T>()

Get combined route and query parameters.

Returns: T extends Record<string, any>

useQueryParams()

Manage URL query parameters.

Returns:

{
  queryParams: QueryParams;
  setQueryParam: (key: string, value: string | undefined) => void;
  setQueryParams: (params: QueryParams, replace?: boolean) => void;
  getQueryParam: (key: string) => string | undefined;
  removeQueryParam: (key: string) => void;
  clearQueryParams: () => void;
}

useNavigate()

Programmatic navigation.

Returns:

{
  navigate: (path: string, options?: NavigateOptions) => void;
  back: () => void;
  forward: () => void;
  go: (delta: number) => void;
  replace: (path: string, options?) => void;
  buildUrl: (path: string, params?, queryParams?) => string;
  canNavigate: () => boolean;
}

useIsActive()

Check if a route is currently active.

Returns:

{
  isActive: (path: string, exact?: boolean) => boolean;
  getActiveClass: (path: string, activeClassName?: string, exact?: boolean) =>
    string;
}

useRouter()

Access router context with all navigation methods and current route state.

usePagination(defaultPage?, defaultLimit?, paramNames?)

Manage pagination with URL state.

Returns:

{
  page: number;
  limit: number;
  setPage: (page: number) => void;
  setLimit: (limit: number) => void;
  nextPage: () => void;
  previousPage: () => void;
  resetPagination: () => void;
}

useFilters<T>(defaultFilters, paramPrefix?)

Manage filters with URL state.

Returns:

{
  filters: T;
  setFilter: (key: keyof T, value: T[key]) => void;
  setFilters: (filters: Partial<T>) => void;
  resetFilters: () => void;
  clearFilter: (key: keyof T) => void;
}

useUrlState<T>(key, defaultValue, serialize?, deserialize?)

Manage single value in URL state.

Returns: [T, (value: T) => void]

Utilities

Route Guards

  • createAuthGuard(isAuthenticated, redirectTo) - Authentication guard
  • createRoleGuard(hasRole, requiredRoles, redirectTo) - Role-based guard
  • createPermissionGuard(hasPermission, requiredPermission, redirectTo) - Permission guard
  • combineGuards(...guards) - Combine guards with AND logic
  • combineGuardsOr(...guards) - Combine guards with OR logic

URL Utilities

  • parseQueryParams(search) - Parse query string
  • buildQueryString(params) - Build query string
  • buildRoutePath(routePath, params) - Build path with parameters
  • normalizePath(path) - Normalize URL path
  • joinPaths(...paths) - Join path segments

Route Matching

  • RouteMatcher - Class for route matching
  • createRouteMatcher(routes, basePath?, caseSensitive?) - Create matcher instance
  • flattenRoutes(routes, parentPath?) - Flatten nested routes

Navigation

  • Navigator - Class for navigation management
  • createNavigator(basePath?, hashMode?) - Create navigator instance

Contributing

Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.