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

@pepys/kit

v0.4.0

Published

Declare a pepys plug-in or deployment: fact families, sources, consumers, tables, links and queries

Readme

Declare a pepys plug-in or deployment with the kit's define* functions.

A plug-in brings one or more sources of data to pepys, such as GitHub. A source sends facts: records of what happened, which pepys never changes. Each source declares its facts, and the routes and timers through which ingest takes them in. The plug-in also declares the consumers that turn facts into table rows, and the queries that read the rows. A deployment lists the plug-ins that one pepys install runs. What a plug-in declares explains each part. The package ships its TypeScript source and runs on Bun.

Install

bun add @pepys/kit
bun add zod@"$(npm view @pepys/kit dependencies.zod)"
bun add -d @types/bun typescript

Install the zod version that the kit pins, as the second line does: a schema from another zod version fails the type check of a define* call.

Test the plug-in with @pepys/testing, and build it with @pepys/cli.

Features

  • @pepys/kit holds the define* functions, the entity ID checks, and checkDeployment, which returns each fault in a deployment, such as two plug-ins that declare the same stream of the fact log. toStreamName and toStreamOffset turn text into the StreamName and StreamOffset types that the fact log functions take.
  • @pepys/kit also holds createLogger, which writes one JSON line per call to any destination, such as an object that pushes each line onto an array in a test. Ingest gives its own logger, as log, to a source's read for each request on a route and to its pull on each timer. Log lines gives the format.
  • @pepys/kit/send holds createFactBatchSender. Give it the source, the URL of the source's ingest route and the route's secret. It posts each batch of facts with the proof that the route's delivery check asks for: an HMAC-SHA256 signature of the body, or the secret as a bearer token.
  • @pepys/kit/generators holds the functions that write a consumer's SQL schema and its boundary file, which holds the TypeScript types of the consumer's rows and operations. pepys build calls them, so a plug-in never imports them.

Entity IDs

An entity ID is text of the form <source>:<kind>:<id>, such as github:pull_request:9001, and its type is EntityID. In a query, or in any code outside a consumer, check text with one of these:

  • isEntityID(text): a type guard that narrows the text to EntityID when it has that form.
  • entityIDSchema: a zod schema that refuses any other text. Use it for each ID field in the input and output of a query. The API serves each query as an MCP tool too, and the tool's JSON Schema shows such a field to an MCP client as a plain string.

A consumer imports neither. pepys build compiles a consumer from a copy of its package's src/ alone, so the consumer builds its IDs with the functions of its own boundary file.

Configuration

Your compiler checks the kit's source with your tsconfig.json, so set at least these options:

{
  "compilerOptions": {
    "target": "ESNext",
    "lib": ["ESNext"],
    "module": "Preserve",
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "verbatimModuleSyntax": true,
    "noEmit": true,
    "strict": true,
    "skipLibCheck": true,
    "types": ["bun"]
  }
}

Documentation

The pepys docs hold the design of the kit and of each part of pepys.