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

@xsynaptic/satteri-reading-time

v0.2.1

Published

Sätteri mdast plugin that computes multilingual reading time and injects it into Astro frontmatter.

Readme

@xsynaptic/satteri-reading-time

A Sätteri mdast plugin that estimates reading time and injects it into Astro's frontmatter, so pages can read it back through remarkPluginFrontmatter. A multilingual-aware take on Astro's official reading time recipe, built for Astro 7 and the Sätteri markdown pipeline.

How it works

Word counting is delegated to @xsynaptic/word-count, which splits text into whitespace-delimited words (Latin, Korean, …) and per-character-script units (CJK, Japanese kana, Thai, etc.). Each class is converted to minutes at its own rate and summed, so mixed-script content is estimated fairly rather than counting ideographs as if they were words:

minutes = ceil(words / latinWpm + scriptChars / scriptCharPerMinute)

What counts

  • Prose, headings, and text inside custom MDX components are counted.
  • Inline code is counted; fenced code blocks are excluded unless countCodeBlocks is set.
  • Image alt text, raw HTML markup, component attributes, imports, expressions, and frontmatter are not counted.
  • The estimate comes from the source, not rendered output, so a self-closing component (<Embed />) contributes nothing regardless of what it renders.

Install

npm install @xsynaptic/satteri-reading-time

This package is ESM-only.

Use

Wire it into the Sätteri processor as an mdast plugin:

import { satteri } from '@astrojs/markdown-satteri';
import { readingTime } from '@xsynaptic/satteri-reading-time';
import { defineConfig } from 'astro/config';

export default defineConfig({
	markdown: {
		processor: satteri({ mdastPlugins: [readingTime()] }),
	},
});

Read the value back through remarkPluginFrontmatter. From a content collection:

---
import { render } from 'astro:content';

const { remarkPluginFrontmatter } = await render(entry);
---

<p>{remarkPluginFrontmatter.minutesRead} min read</p>

Or from a directly imported .mdx page, the injected value is merged into the module's frontmatter export:

---
import Post, { frontmatter } from '../post.mdx';
---

<p>{frontmatter.minutesRead} min read</p>

A document with no countable prose (frontmatter only, or nothing but an image) leaves the key unset, so treat a missing value as "no reading time."

Options

| Option | Default | Purpose | | --------------------- | --------------- | --------------------------------------------------------------------- | | frontmatterKey | 'minutesRead' | Frontmatter key the estimate is written to. | | latinWpm | 200 | Words per minute for whitespace-delimited scripts (Latin, Korean, …). | | scriptCharPerMinute | 300 | Characters per minute for per-character scripts (CJK, kana, Thai, …). | | countCodeBlocks | false | Include fenced code block contents in the estimate. |

A single scriptCharPerMinute covers every space-free script, so it is an approximation for the non-CJK ones (Thai is read at a difference pace). Calibrate it for the mix of languages in your content.

License

MIT