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

@b4moss/median

v0.10.0

Published

Median media store (TypeScript) — Store/Delete/Get/PresignGet with local/S3, DB, image pipeline, SVG sanitize, PDF thumbnails

Readme

@b4moss/median

TypeScript port (packages/js). npm: @b4moss/median
Current: 0.10.0 (git tag v0.10.0). Requires Node.js 24+.

Language-port hub for JS/TS. Cross-language product overview and host workflow: root README. Specs: docs/specs/.

Install

npm install @b4moss/median

CLI (after install / via npx):

npx @b4moss/median migrate dump --dialect postgres --table media

package.json maps bin.median → ./dist/cli.js (built on publish).

Layout

| Path | Role | | --- | --- | | src/core | createMedian / store / delete / get / presignGet | | src/storage | local / s3 | | src/db | createMediaSQL / migrateUp / MediaRepo | | src/cli.ts | CLI (migrate dump) | | src/pipeline | process / sanitizeSvg / PDF thumbs | | src/internal | MIME / filename / shardian path |

DB note: JS does not use crudian. Runtime MediaRepo is SQLite (better-sqlite3). DDL string generation still supports mysql / postgres / sqlite3 for host dumps.

Step-by-step (Node host)

Shared host workflow (all languages): root README.

1. Install

npm install @b4moss/median

2. Create the media table (production)

npx @b4moss/median migrate dump \
  --dialect postgres \
  --id-strategy auto_increment \
  --table media \
  > migrations/XXXX_median_media.sql

| Flag | Required | Default | | --- | --- | --- | | --dialect | yes | — (mysql | postgres | sqlite3) | | --id-strategy | no | auto_increment | | --table | no | media |

Commit the SQL into your migrate tool, then run it. Match flags with db config below.

For unit tests, migrateUp(db, "sqlite3", ID_AUTO_INCREMENT) on an in-memory better-sqlite3 is fine.

Existing tables + column maps: skip the CLI; see db-media.

3. Create a client

import Database from "better-sqlite3";
import {
  createMedian,
  migrateUp,
  ID_AUTO_INCREMENT,
} from "@b4moss/median";

const sql = new Database("app.sqlite");
// Dev/demo only — production should apply CLI dump via host migrations:
migrateUp(sql, "sqlite3", ID_AUTO_INCREMENT);

const median = await createMedian({
  storages: {
    local: { driver: "local", path: "./data/median" },
  },
  defaultKey: "local",
  defaultActor: "system",
  db: {
    db: sql,
    idStrategy: ID_AUTO_INCREMENT,
    tableName: "media",
  },
});

const body = Buffer.from("hello");
const stored = await median.store(body, body.length, {
  mime: "text/plain",
  filename: "hello.txt",
});
console.log(stored.path, stored.hash);

const got = await median.get(stored.path, { withBody: true });
console.log(got.body?.toString());

await median.delete(stored.path);

S3 storage entry sketch:

s3: {
  driver: "s3",
  bucket: "my-bucket",
  region: "ap-northeast-1",
  endpoint: "https://s3.example",
  forcePathStyle: true,
  prefix: "uploads/",
  accessKey: "...",
  secretKey: "...",
},

4. Library DDL (optional)

import { createMediaSQL, ID_AUTO_INCREMENT } from "@b4moss/median";

const sqlText = createMediaSQL("postgres", ID_AUTO_INCREMENT, "media");

Same payload as the CLI for the same arguments.

Develop / test

cd packages/js
npm ci
npm test
npm run test:coverage
npm run build

Release

Root git tag vX.Y.Z must match package.json version. Pushing that tree to release publishes to npm when packed content differs (.github/CI.md). Trusted Publishing on GitHub Actions.

Docs