chromite
v0.3.3
Published
Chrome Extension Message-Routing toolkit
Maintainers
Readme
chromite — Chrome Extension Messaging Routing Kit
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
consoleoutput with leveled, namespaced logging. - Ship TypeScript types and modern build artifacts out of the box.
Installation
npm install chromite
# or
yarn add chromiteChromite 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.,
webRequestAPI). - Client: Wraps
chrome.runtime.sendMessagewith 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.onMessagetypeof chrome.tabs.onActivatedtypeof 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 intests/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:
- Run the lint and test commands listed above (include logs in the PR).
- Verify documentation changes stay consistent with the rest of the repo.
- Provide context for any manifest or permission updates.
Issues and feature requests are welcome through GitHub Discussions or Issues.
License
MIT © otiai10
