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

@masonjames/emdash-plugin-reading-time

v0.1.0

Published

Reading time plugin for EmDash CMS with editor blocks, theme components, and sitewide defaults

Downloads

55

Readme

EmDash Reading Time

Reading Time is a native EmDash plugin that gives you a polished, reusable reading-time badge for long-form content.

  • Editors can insert a readingTime Portable Text block.
  • Theme authors can import a dedicated Astro component for explicit placement near titles, heroes, or metadata rows.
  • Admins can define sitewide reading-time defaults for words per minute, label format, and counting rules.

The package is intentionally small and operationally boring:

  • no routes
  • no required capabilities
  • no plugin storage
  • no migrations

Status

This is a trusted/native plugin for EmDash today.

That is not a marketing choice—it is a current platform constraint. EmDash’s Portable Text plugin blocks and componentsEntry rendering are native-only, so this package cannot be installed as a sandboxed marketplace plugin without losing core features.

Official distribution path

Today, the supported distribution path for this package is:

  1. publish the package to npm
  2. install it in an EmDash site
  3. register it in astro.config.mjs

emdash plugin publish targets the EmDash marketplace flow for bundled marketplace tarballs. Current EmDash docs and runtime constraints make that path incompatible with a plugin that needs componentsEntry and Portable Text block types.

Install

npm install @masonjames/emdash-plugin-reading-time

Register the plugin

// astro.config.mjs
import { defineConfig } from "astro/config";
import { emdash } from "emdash";
import { readingTimePlugin } from "@masonjames/emdash-plugin-reading-time";

export default defineConfig({
	integrations: [
		emdash({
			plugins: [readingTimePlugin()],
		}),
	],
});

What you get

1. Sitewide plugin settings

The plugin adds settings for:

  • words per minute
  • label template
  • include headings
  • include captions
  • ignore code blocks
  • short-content behavior

2. A readingTime Portable Text block

Editors can insert Reading Time from the slash menu and optionally override:

  • display style
  • manual minutes
  • custom label
  • prefix text
  • words per minute
  • counting rules
  • short-content behavior

3. A theme component for explicit placement

---
import { ReadingTimeBadge } from "@masonjames/emdash-plugin-reading-time/components";

const { post } = Astro.props;
---

<ReadingTimeBadge content={post.content} variant="pill" />

This is the recommended path for consistent, fully automatic output.

Theme usage examples

Basic badge

---
import { ReadingTimeBadge } from "@masonjames/emdash-plugin-reading-time/components";

const { article } = Astro.props;
---

<ReadingTimeBadge content={article.content} />

Custom label template

<ReadingTimeBadge
	content={article.content}
	labelTemplate="Approx. {minutes} minutes"
	variant="compact"
/>

Manual override for unusual formats

<ReadingTimeBadge
	content={article.content}
	manualMinutes={12}
	prefixText="Estimated"
/>

Editor-placed block vs theme placement

EmDash Reading Time deliberately supports explicit placement in two ways:

Theme placement

Best when you want the same badge position on every article.

Editor placement

Best when a team wants per-article control inside Portable Text.

Important caveat

Portable Text type renderers typically only receive the current block node. Because reading-time calculation needs the surrounding article content, the plugin’s auto-wired readingTime block can only calculate automatically when the renderer is given article content by the theme.

In practice:

  • Theme component placement is the most reliable fully automatic path.
  • Editor-placed blocks are great for manual minutes or custom labels out of the box.
  • If your theme passes the surrounding Portable Text array into the block renderer, editor-placed blocks can also calculate automatically.

Defaults

The plugin ships with these safe defaults:

{
	wordsPerMinute: 200,
	labelTemplate: "{minutes} min read",
	includeHeadings: true,
	includeCaptions: false,
	ignoreCodeBlocks: true,
	shortContentBehavior: "one_min"
}

Short-content behavior

For posts under one minute, choose one of:

  • one_min1 min read
  • less_than_one< 1 min read
  • hide → render nothing

Duplicate badge guidance

Use editor placement or theme placement, not both, unless you intentionally want two badges.

Public exports

Descriptor

import { readingTimePlugin } from "@masonjames/emdash-plugin-reading-time";

Runtime entrypoint

Used internally by the descriptor:

import createPlugin from "@masonjames/emdash-plugin-reading-time/plugin";

Auto-wired Astro block components

import { blockComponents } from "@masonjames/emdash-plugin-reading-time/astro";

Explicit theme components

import { ReadingTimeBadge } from "@masonjames/emdash-plugin-reading-time/components";

Stable EmDash note

The public emdash npm package does not currently expose a stable site-side helper for reading persisted plugin settings during Astro render. This package therefore:

  • always works with its built-in defaults
  • supports explicit settings={...} passed by the theme
  • automatically uses persisted plugin settings when that helper is available in the host EmDash runtime

Requirements

  • EmDash 0.1.0 or newer
  • Astro 6 or newer
  • Trusted/native plugin installation via plugins: []

Development

npm test
npm run typecheck

Roadmap note

If EmDash later supports Portable Text plugin blocks and site-side components in sandboxed plugins, this package can grow a marketplace-safe variant. Until then, the native/trusted format is the honest and correct shape for full feature parity.