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

@nkwib/promptregistry

v0.2.1

Published

Turn a static prompt manifest into typed, greppable named imports with lockfile-gated integrity

Readme

PromptRegistry

An OSS TypeScript SDK + CLI that turns a static prompt manifest into typed, greppable named imports with lockfile-gated integrity.

The wedge is two things together: a typed pull (each prompt entry is emitted as a runtime .ts with a named XxxVars type alias, so a missing variable is a normal tsc error that names the prompt) and lockfile-gated Placeholder integrity (the manifest hash is committed in prompt-lock.json, and promptregistry check fails if the remote was edited without a version bump). Built on the promptkit tagged-template primitive — see promptkit's CONTEXT.md for the canonical vocabulary (Placeholder, Variables object, Compiled template, Parser). Non-goals: no hosted UI, no eval running, no migration importers, no template logic — variables only.

A PM edits the remote manifest and removes a variable:

manifest before/after

The next tsc --noEmit on a consumer's repo names the offending prompt and the removed variable:

rewritten tsc error

What it does

  1. Static manifest — a JSON file hosted on GitHub raw, a release asset, or a public bucket. Each entry has a name, version, template string, and delimiter.
  2. promptregistry codegen — fetches the manifest, emits one runtime .ts per prompt (typed via a named XxxVars alias), and writes a registry.ts barrel with named exports.
  3. Lockfile integrityprompt-lock.json pins each prompt to its content hash. promptregistry check fails if the remote was edited without a version bump.
  4. Human tsc errors — because each prompt's variables are exported as a named type, tsc's native error already calls out the prompt: ... not assignable to parameter of type 'CustomerSummaryVars'. promptregistry check --tsc adds an extra pass that rewrites diagnostics from the generated files themselves.

Quick start

npm install @nkwib/promptregistry

Create a manifest.json:

{
  "manifest-format-version": "1",
  "prompts": [
    {
      "name": "customer-summary",
      "version": "v1",
      "template": "Summarize the account for {{customerName}} on the {{planTier}} plan.",
      "delimiter": { "open": "{{", "close": "}}" }
    }
  ]
}

Generate types:

npx promptregistry codegen --manifest ./manifest.json --out ./prompts/.generated

Import and use (NodeNext requires the .js extension on the source-side import):

import { customerSummary } from './prompts/.generated/registry.js'

// Missing a variable? tsc catches it before it reaches the model.
const output = customerSummary.with({
  customerName: 'Ada',
  planTier: 'Pro',
})

Wire into your build script:

{
  "scripts": {
    "typecheck": "promptregistry check && tsc --noEmit"
  }
}

Relationship to promptkit

PromptRegistry is built on the promptkit tagged-template primitive and reuses promptkit's vocabulary verbatim — see promptkit's CONTEXT.md for the canonical definitions of Placeholder, Variables object, Compiled template, and Parser. PromptRegistry adds the operational layer on top: a Manifest as the source of truth, a typed pull via codegen, and a Lockfile-backed integrity gate. The package does not redefine those promptkit terms; if a section reads as if it does, file a bug.

API reference

See docs/api.md for the manifest schema, pin grammar, lockfile shape, generated module shape, and per-command CLI reference.

CLI commands

| Command | Purpose | |---------|---------| | promptregistry codegen | Generate runtime .ts files and registry.ts from the manifest | | promptregistry check | Cross-check manifest, lockfile, and generated files | | promptregistry check --tsc | Run tsc --noEmit and rewrite diagnostics | | promptregistry lock | Write prompt-lock.json from the current manifest | | promptregistry init | Scaffold manifest from existing prompt() call-sites |

Configuration

Create promptregistry.config.json:

{
  "manifestUrl": "https://example.com/manifest.json",
  "srcRoots": ["./src"],
  "outDir": "./prompts/.generated"
}

Or pass flags: --manifest <url>, --src <dirs>, --out <dir>.

Non-goals

  • No hosted web UI in v1
  • No eval running — use promptfoo for that
  • No migration importers from Langfuse or PromptLayer
  • No template logic ({{#if}}, loops) — variables only

License

MIT