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

@kernhq/module-quire

v0.7.3

Published

Kern Quire: collaborative documents, spaces and page trees

Readme

Module template

Copy this to start a Kern module. It is a working module: a Note entity with list, create and delete, its own Postgres schema, row-level security, permissions, events, and a test that refuses to let the contract and the router drift apart.

The fastest way to copy it correctly is not to copy it by hand:

cd repos/modules
pnpm new-module crm          # generates this package *and* its half in the app

Read the rest of this file if you are doing it by hand, or if you want to know what the generator wrote.

What is in here

| File | What it is | |---|---| | src/contract.ts | Zod models, the oRPC contract, events, permission keys, capabilities. Imported by both halves, so no Node code. | | src/server/schema.ts | Drizzle tables in mod_<id>. | | src/server/_impl.ts | The router. Separate from index.ts so the test can walk it without a kernel. | | src/server/index.ts | defineServerModule — schema, migrations, router, subscriptions. | | src/client/index.ts | The typed API client and module logic. Ships as source. | | src/module.test.ts | Contract-to-router parity and the authorisation guard. Keep it. | | migrations/0000_init.sql | Generated by pnpm db:generate. | | migrations/0001_rls.sql | Hand-written. Never generated. |

Copying it by hand

Each of these has been got wrong before.

  1. package.json — set name to @kernhq/module-<id>, and delete "private": true. A private package is skipped silently by changesets: the commit lands, CI is green, and nothing publishes.
  2. files must cover every directory ./client reaches — src/client and src/contract. The client ships as source, so a re-export the tarball omits breaks the consumer and nothing local notices, because the workspace resolves the file the package does not ship. pnpm check:pack catches it.
  3. The id agrees in four places: MODULE_ID, moduleSchema('<id>'), schemaFilter in drizzle.config.ts, and every permission and event prefix.
  4. Version comes from the package, never a literal: packageVersion(import.meta.url). A literal is not bumped by a release — chat once shipped as 0.2.0 while telling every admin it was 0.1.0, and that literal is what workspace_modules.installed_version recorded.
  5. Write the RLS migration. pnpm db:generate will not. Copy 0001_rls.sql and change the table names; rlsPolicySql from @kernhq/kernel emits the same text.
  6. Host it. A module nothing imports is invisible: its tests pass, it publishes, and every call 404s. Add it to featureModules in the core repo's src/service.ts, or to whichever service should hold it.
  7. Register the client in the app's src/lib/modules/registry.ts.

What a module can contribute

The server half declares tables, migrations, a router, procedures other modules call through kernel.call(), jobs, subscriptions, search indexers and lifecycle hooks.

The client half — the manifest in the app — declares nav, commands, settingsPages, widgets for the dashboard, and sidebar for the column beside the rail. Read the kern-widget skill before writing a widget, and kern-module for the whole sequence.

Before you call it done

pnpm typecheck && pnpm lint && pnpm test && pnpm build
pnpm check:pack        # the tarball contains what ./client imports
pnpm check:versions    # the manifest version matches package.json

Then use it through the interface, signed in, with the module enabled for a workspace. A module that has never served a request is not finished, whatever the type-checker says.