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

chromite

v0.3.3

Published

Chrome Extension Message-Routing toolkit

Readme

chromite — Chrome Extension Messaging Routing Kit

version downloads Node.js CI Chrome E2E Test codecov Maintainability

Chromite streamlines Chrome extension messaging by giving you familiar routing, request handling, and logging primitives. Instead of wiring every message in a single onMessage listener, compose controllers, share request clients, and format logs with a consistent API.

Features

  • Route extension messages with path patterns and controller handlers.
  • Use a client abstraction to send structured messages without manual payloads.
  • Decorate console output with leveled, namespaced logging.
  • Ship TypeScript types and modern build artifacts out of the box.

Installation

npm install chromite
# or
yarn add chromite

Chromite targets modern Chromium-based extensions (Manifest V3). Pair it with TypeScript for the best DX.

Quick Start

import { Router, Client, Logger, LogLevel } from "chromite";

const router = new Router();

router.on("/users/list", async () => {
  return { users: await Users.getAll() };
});

router.on("/users/{id}", async function () {
  const user = await Users.get(this.id);
  return { user };
});

router.onNotFound(() => ({ message: "Not found" }));

chrome.runtime.onMessage.addListener(router.listener());

const client = new Client(chrome.runtime);
const logger = Logger.get("chromite-demo", { level: LogLevel.INFO });

const users = await client.send("/users/list");
logger.info("Loaded users", users);

Logger tips

// Reuse the same logger for a project namespace.
const logger = Logger.get("popup");

// Raise verbosity for every registered logger.
Logger.setLevel(LogLevel.DEBUG);

// Tweak shared visual configuration.
Logger.setEmoji({
  [LogLevel.INFO]: "✨"
});
Logger.setStyle({
  [LogLevel.ERROR]: "color:white; background-color:#d93025; font-weight:bold;"
});

logger.error("Failed to fetch", { status: 500 });

Core Concepts

  • Router: Registers path-based handlers and resolves parameters before delegating to controllers.
  • SequentialRouter: Similar to Router but maintains a history of events, useful for sequential request tracking (e.g., webRequest API).
  • Client: Wraps chrome.runtime.sendMessage with promise-based ergonomics.
  • Logger: Formats messages with namespaced prefixes and log levels for easier debugging.

Advanced: Using SequentialRouter with Chrome Events

When working with Chrome events like webRequest, use typeof to specify the event type:

import { SequentialRouter } from "chromite";

const router = new SequentialRouter<typeof chrome.webRequest.onBeforeRequest>(
  2,
  async (details) => {
    const url = new URL(details.url);
    return { __action__: url.pathname };
  }
);

router.on(["/api/users"], async (stack) => {
  // stack contains the last 2 events
  console.log("Request history:", stack);
});

chrome.webRequest.onBeforeRequest.addListener(
  router.listener(),
  { urls: ["*://example.com/*"] },
  ["requestBody"]
);

This pattern works with any Chrome event type, including:

  • typeof chrome.runtime.onMessage
  • typeof chrome.tabs.onActivated
  • typeof chrome.webRequest.onCompleted

See src/ for the TypeScript source and lib/ for compiled artifacts published to npm.

Development Workflow

  • npm run clean — remove build output for a fresh compilation.
  • npm run build — compile TypeScript and emit declarations.
  • npm run lint — run ESLint (standard-with-typescript) on source and tests.
  • npm run test — execute Jest unit tests in tests/spec/.
  • npm run test:e2e — rebuild the demo extension and launch Puppeteer suites.

End-to-end fixtures live in tests/e2e/, and coverage reports land in coverage/.

Contributing

Chromite follows Japanese Conventional Commits and documents required review steps in AGENTS.md. Before opening a pull request:

  1. Run the lint and test commands listed above (include logs in the PR).
  2. Verify documentation changes stay consistent with the rest of the repo.
  3. Provide context for any manifest or permission updates.

Issues and feature requests are welcome through GitHub Discussions or Issues.

License

MIT © otiai10