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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vydra-js/router

v0.0.1

Published

Declarative routing for Web Components with support for both SPA and microfrontend modes. Handles route matching, navigation guards, and lazy loading.

Readme

@vydra-js/router

Declarative routing for Web Components with support for both SPA and microfrontend modes. Handles route matching, navigation guards, and lazy loading.

Installation

npm install @vydra-js/router

Quick Start

import { VydraRouter, RouteConfig } from '@vydra-js/router';

const routes: RouteConfig[] = [
  { path: '/', tag: 'home-page' },
  { path: '/about', tag: 'about-page' },
  { path: '/users/:id', tag: 'user-page' },
];

const router = new VydraRouter({
  basePath: '/',
  mountPoint: document.getElementById('app')!,
  outlet: document.createElement('vydra-outlet'),
  routes,
});

router.init();

API

VydraRouter

Main router class.

new VydraRouter(options: VydraRouterOptions)

Options

| Option | Type | Required | Description | | ------------ | --------------- | -------- | ---------------------- | | basePath | string | Yes | Base URL path | | mountPoint | HTMLElement | Yes | Element to render into | | outlet | HTMLElement | Yes | Outlet component | | routes | RouteConfig[] | Yes | Route definitions |

Methods

init(): Promise<void>

Initializes router and performs initial navigation.

await router.init();
navigate(path: string, options?: NavigateOptions): Promise<void>

Programmatic navigation.

await router.navigate('/about');
await router.navigate('/users/123', { replace: true });

Route Configuration

interface RouteConfig {
  path: string;
  tag: string;
  children?: RouteConfig[];
  guards?: RouteGuardFn[];
  loader?: () => Promise<any>;
}
path

Route pattern with parameter support:

  • /users - exact match
  • /users/:id - parameter
  • /users/* - wildcard
tag

Custom element tag to render when route matches.

children

Nested routes (inferred from codebase patterns).

guards

Route protection functions.

loader

Lazy load function for code splitting.

Navigation Options

interface NavigateOptions {
  replace?: boolean;
  state?: Record<string, unknown>;
}

VydraActivatedRoute

Current active route information.

interface VydraActivatedRoute {
  path: string;
  params: Record<string, string>;
  query: Record<string, string>;
  data: Record<string, unknown>;
}

Concepts

Why Vydra Router?

  • Framework agnostic: Works with any Web Component
  • Microfrontend ready: Built-in support for cross-MF navigation
  • Lazy loading: Route-based code splitting
  • Type-safe: Full TypeScript support
  • Event-driven: Emits navigation events via Event Bus

Navigation Lifecycle

  1. User clicks link or calls navigate()
  2. Router checks guards
  3. Route matching via regexparam
  4. Component loading (if lazy)
  5. Outlet renders component
  6. Navigation event emitted

Usage Examples

Basic SPA Routing

import { VydraRouter } from '@vydra-js/router';

const routes = [
  { path: '/', tag: 'home-page' },
  { path: '/products', tag: 'products-page' },
  { path: '/products/:id', tag: 'product-detail' },
];

const router = new VydraRouter({
  basePath: '/',
  mountPoint: document.getElementById('app')!,
  outlet: document.createElement('vydra-outlet'),
  routes,
});

await router.init();

Lazy Loading Routes

const routes: RouteConfig[] = [
  {
    path: '/admin',
    loader: () => import('./admin/admin-page'),
    tag: 'admin-page',
  },
];

Route Guards

const routes: RouteConfig[] = [
  {
    path: '/dashboard',
    tag: 'dashboard-page',
    guards: [
      async () => {
        const auth = Inject(AuthService);
        if (!auth.isAuthenticated()) {
          return '/login';
        }
        return true;
      },
    ],
  },
];

Microfrontend Navigation

const router = new VydraRouter({
  basePath: '/app',
  mountPoint: document.getElementById('app')!,
  outlet,
  routes,
  onRedirectMicrofrontend: (nav) => {
    new VydraBus('global').emit('mf:switch-request', nav);
  },
});

await router.init();

Programmatic Navigation

class MyComponent extends LitElement {
  private router = new VydraRouter({
    /* options */
  });

  gotoAbout() {
    this.router.navigate('/about');
  }

  gotoUser(id: string) {
    this.router.navigate(`/users/${id}`);
  }
}

Integration

With Event Bus

Router emits navigation events:

import { VydraBus } from '@vydra-js/bus';

const bus = new VydraBus('global');
bus.subscribe('router:navigate', (event) => {
  console.log('Navigated to:', event.detail.path);
});

With Core

Router integrates with @vydra-js/core:

import { VydraNavigationService } from '@vydra-js/core';

const nav = new VydraNavigationService();
nav.navigate('/about'); // Uses router internally

Best Practices

  1. Define routes in a separate file

    // router.ts
    export const routes = [...]
  2. Use lazy loading for large pages

    { path: "/admin", loader: () => import("./admin") }
  3. Implement guards for protected routes

    { path: "/profile", guards: [requireAuth] }
  4. Handle 404 routes

    { path: "**", tag: "not-found-page" }

Type Definitions

type RouteGuardFn = (route: VydraActivatedRoute) => boolean | string | Promise<boolean | string>;

interface NavigateOptions {
  replace?: boolean;
  state?: Record<string, unknown>;
}

See Also