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

@aegisjsproject/atlas

v1.0.2

Published

A client-side router library using `Navigation` & `URLPattern`

Readme

@aegisjsproject/atlas

A client-side router library using Navigation & URLPattern

CodeQL Node CI Lint Code Base

GitHub license GitHub last commit GitHub release GitHub Sponsors

npm node-current npm bundle size gzipped npm

GitHub followers GitHub forks GitHub stars Twitter Follow

Donate using Liberapay


Overview

This router intercepts same-origin navigations and resolves them to registered route modules. Each module can return content in multiple native formats (e.g. Response, Document, Element), allowing flexibility without imposing rendering constraints.

Key characteristics:

  • Native Navigation API (navigation)
  • Route-to-module mapping via dynamic import()
  • Direct DOM updates (no diffing layer)
  • Supports HTML streaming via Response
  • Built-in metadata handling (title, description, styles)
  • Optional preload observation
  • Abort-safe lifecycle with AbortController and DisposableStack

[!IMPORTANT] This requires the Navigation API, which is Baseline 2026. It also creates a Trusted Types Policy, where supported, labeled "aegis-atlas#html" for handling HTML responses without sanitizer restrictions.

[!TIP] Route module specifiers can use bare specifiers like @acme/blog. These can be resolved via an import map, for example:

<script type="importmap">
{
  "imports": {
    "@acme/blog": "https://cdn.example.com/acme-blog/index.js"
  }
}
</script>

This allows modules to be loaded from a CDN without changing route definitions.


Installation

This module is intended to be used directly in modern browser environments.

import { init } from '@aegisjsproject/atlas';

No dependencies required.


Core Concepts

Route Modules

Each route resolves to a module with the following shape:


export default async function handler(request, context) {
	return new Response('<h1>Hello</h1>', {
		headers: { 'Content-Type': 'text/html' }
	});
}

export const title = 'Page Title';

export const description = 'Page description';

export const styles = new CSSStyleSheet();

Supported Exports

  • default (required)
    • Function: (Request, RouteContextObject) => HandlerResult
    • Or static value: HandlerResult
  • title (optional)
  • description (optional)
  • styles (optional: CSSStyleSheet or array)

Handler Return Types

Handlers may return:

  • Response (must be text/html)
  • HTMLDocument
  • Element
  • DocumentFragment
  • URL (triggers navigation)

Route Context

Each handler receives a context object:

{

	result,        // URLPatternResult
	params,        // extracted route params
	stack,         // DisposableStack
	controller,    // AbortController
	signal,        // AbortSignal
	type,          // navigation type
	url,           // URL instance
	state,         // navigation state
	info,          // navigation info
	timestamp      // performance timestamp
}

Usage

Initialize Router


init({
	'/': '/routes/home.js',
	'/users/:id': '/routes/user.js'
	'/posts/:year(\\d{4})/:month(\\d{2})/:day(\\d{2})/:slug': '@acme/blog',
	'/product/:sku': '@acme/store/product',
}, {
	root: 'app',
	preload: true
});

Options

  • root: Element or element ID where content is rendered
  • preload: Enable preload observation
  • signal: Optional AbortSignal for teardown

Navigation Helpers


import { navigate, back, forward, reload } from './router.js';

navigate('/about');
back();
forward();
reload();

Navigation Lifecycle

Wait for navigation completion:

import { whenLoaded } from './router.js';

await whenLoaded();

Behavior Details

Interception Rules

Navigation is intercepted only if:

  • event.canIntercept is true
  • URL is same-origin
  • Triggering element does not have .no-router

Content Handling

Response

  • Must be text/html
  • Parsed via Document.parseHTMLUnsafe
  • Re-processed as HTMLDocument

HTMLDocument

  • Updates:
    • document.title
    • meta description
    • root content

Element / DocumentFragment

  • Directly replaces root children

URL

  • Triggers navigation

Root Management


setRoot('app');

// or

setRoot(document.getElementById('app'));

If root is <body>, full body is replaced.

If root is an element with id, only matching subtree is replaced.


Metadata Updates

Route modules can define:

  • title → updates document.title
  • description → updates all matching meta tags:
    • name="description"
    • og:description
    • twitter:description
  • styles → appended to document.adoptedStyleSheets

Form Handling

  • Automatically determines method (GET or POST)
  • Submits FormData when applicable
  • Uses Request API for consistency

Abort + Cleanup

Each navigation:

  • Uses AbortController
  • Combines signals via AbortSignal.any
  • Cleans up via DisposableStack

Handlers should respect context.signal where applicable.


Trusted Types

If supported, a Trusted Types policy is used to safely pass HTML into:


Document.parseHTMLUnsafe(...)

This ensures CSP compatibility without stripping critical markup like:

  • <iframe>
  • inline event handlers
  • form attributes

Example Route


export default async function(request, { params }) {
	return new Response(`
		<h1>User ${params.id}</h1>
	`, {
		headers: { 'Content-Type': 'text/html' }
	});
}

export const title = 'User Profile';
export const description = 'User details page';

Notes

  • Only text/html responses are supported for Response
  • Non-matching routes fall back to fetch()
  • Errors during routing are surfaced via reportError
  • Designed for modern browsers with Navigation API support

Summary

This router provides a low-level, high-control alternative to framework routers by:

  • Eliminating abstraction layers
  • Leveraging native platform APIs
  • Supporting flexible content types
  • Maintaining strict control over navigation lifecycle

Intended for environments where performance, control, and minimal overhead are priorities.