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

@supersuit/bring-up

v0.1.2

Published

To Bring Up: each person's private list of things to raise the next time they talk. Rules, a Firestore store, Next.js route handlers and a React list, for any app that says who is signed in and where items are kept.

Readme

@supersuit/bring-up

To Bring Up: each person's own private list of things to raise the next time they talk to someone, so the day is not a stream of texts. Nobody else can see a list, not even that it exists: an item that is not yours answers exactly as one that does not exist. Items are checked off as they are talked about, and a person's own agent can add to their list from the desk.

The package knows how the feature works. The app says who is signed in, which agent key acts as which person, where items are kept, and how they look.

Install

npm install @supersuit/bring-up

Peers: react and react-dom 19, and firebase-admin 13 for the server entry. With Tailwind 4, add one line to the stylesheet that imports Tailwind, so the list's classes are generated:

@source "../node_modules/@supersuit/bring-up/dist";

Three entry points

  • @supersuit/bring-up: the types and every rule, pure, safe anywhere (sortAgenda, agendaTile for a home tile, applyAgendaPatch, ...).
  • @supersuit/bring-up/server: createBringUpStore(host) and createBringUpHandlers(host). Server only.
  • @supersuit/bring-up/client: AgendaList, BringUpProvider, setTheme.

The host

import type { BringUpHost } from '@supersuit/bring-up/server'

export const host: BringUpHost<'a' | 'b'> = {
  member: async () => /* who is signed in, or null */ null,
  agentMember: async (req) => /* the person this request's agent key acts as, or null */ null,
  db: () => getFirestore(),   // called on use, never at import
  collection: 'agenda',       // the list items are kept in
  // isRefusal: (err) => err instanceof MyAppRefusal,   // optional
}

What the host is responsible for

agentMember is where the package hands off a security decision, and the package cannot check it for you. The host must:

  • compare the presented agent key in constant time (for example crypto.timingSafeEqual over equal-length digests), never with ===;
  • map each key to exactly one member, and never let two members share a key, because the key alone decides whose list an agent reads and writes;
  • return null for a missing, malformed or unknown key.

member must likewise return only the person the request is authenticated as.

isRefusal

This package's own refusals (RuleError) always reach the client with their message and status: 403 private for a stranger, 401 unauthorized for an agent without a valid key, 404 not found for an item that is not yours, 400 for a body it cannot take. Every other error is logged on the server and answers an opaque 500.

An app with refusals of its own passes isRefusal to say which of ITS errors may be shown too. The hook ADDS to the package's refusals and never replaces them. An error is never shown merely because it carries a 4xx status. A refusal answers with its status when that is 400-499, and 403 when it has none; a refusal carrying any other status is a bug and is answered as an internal error.

Mounting the handlers

// app/api/agenda/route.ts
export const runtime = 'nodejs'
export const { GET, POST, DELETE } = createBringUpHandlers(host).list
// app/api/agenda/[id]/route.ts: export const { PATCH, DELETE } = createBringUpHandlers(host).item
// app/api/agenda/agent/route.ts: export const { GET, POST } = createBringUpHandlers(host).agent

GET lists the signed-in person's items, POST { text } adds one (201), and DELETE on the list clears what is checked off ({ cleared }). On an item, PATCH { kind: 'done', value } or { kind: 'text', text } changes it, and DELETE removes it (204). The agent routes read and add to the one list the key's person owns. A refusal answers { error } with its status; a stranger gets 403, an agent without a valid key 401.

The screen

<BringUpProvider theme={{ serif, ink, muted, hairline, onInk }}>
  <AgendaList initial={items} otherName="the other person" apiBase="/api/agenda" />
</BringUpProvider>

initial comes from createBringUpStore(host).listAgenda(member) in a server component.

Releasing

A release is a version tag. Bump version (npm version <x.y.z> --no-git-tag-version), add the CHANGELOG entry, commit package.json and package-lock.json together (npm ci refuses a release whose lockfile does not match the version), push, then git tag v<x.y.z> && git push origin v<x.y.z>. GitHub Actions tests, builds and publishes through npm trusted publishing. Nothing is ever published from a laptop.