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

count-read-time

v1.0.2

Published

An enterprise-grade, highly scalable reading time estimator with technical content weighting and image compensation.

Readme

Read-Time: The Enterprise level reading-time estimator

Zero Dependencies Build Status JS & TS Support ESM & CJS License

An impossibly lightweight, highly accurate reading time calculator built for the modern web.


Why did we build this?

If you search npm, you'll find plenty of reading-time libraries with millions of downloads. But as developers who write highly technical blogs, we noticed they all share a few fatal flaws:

  1. The Code Blindspot: Existing tools parse everything at ~200 Words Per Minute. But reading a complex JavaScript algorithm takes much more cognitive load than reading a standard English paragraph. If an article is 50% code, standard libraries underestimate the reading time significantly.
  2. The Image Blindspot: A great technical post relies on architecture diagrams. Older tools completely ignore <img> tags, acting as if studying a complex flowchart takes zero seconds.
  3. Format Lock-In: Most parsers expect pristine HTML. But today, we write in Markdown, MDX, or custom CMS text formats.
  4. Poor Developer Experience: They just spit out raw numbers, forcing you to write your own UI string formatting logic every single time.

We wanted to fix this.

Introducing: The Universal Engine

count-read-time is a zero-dependency micro-library that intelligently calculates accurate reading times by respecting technical content.

  • 🧠 Technical Weighting: It uses a dual-speed engine. Standard text is parsed at a breezy 200 WPM, but code blocks (whether <pre> or Markdown ```) are automatically throttled to a careful 100 WPM.
  • 🖼️ Medium's Image Math: It dynamically adds time for every image it finds using a degrading scale (12s for the first image, 11s for the second, 10s for the third, and 3s for any subsequent images).
  • 🌐 Format Agnostic: Pass it HTML, Markdown, MDX, or just a massive string of plain text. The Universal Engine parses it all simultaneously with zero configuration required.

The 4 Formatting Modes

We believe a library should handle the UI heavy lifting for you. Out of the box, count-read-time gives you four distinct formatting modes to perfectly match your blog's aesthetic:

| Mode | Example Output | Best Used For | | :--- | :--- | :--- | | Standard (Default) | "5 min read" | Clean, minimal, professional blogs. | | Coffee | "☕ ☕ 10 min read" | Cozy tech blogs. Calculates exactly 1 cup per 5 minutes of reading! | | Hourglass | "⏳ 3 mins" | Urgent, short-form content or documentation. | | Raw | { seconds: 120, minutes: 2 } | Backend databases, API responses, or completely custom UIs. |


Installation

Because it is 100% dependency-free, you can safely install it in any project without bloating your node_modules.

npm install count-read-time

Usage in Any Stack

count-read-time is natively compatible with ES Modules (Next.js, modern React) and CommonJS (legacy Express/Node). It even comes with index.d.ts for full TypeScript auto-completion.

⚛️ Next.js / React

import { estimateReadTime } from 'count-read-time';

export default function BlogPost({ postContent }) {
    // 1. Pass your Markdown, MDX, or HTML directly
    const readTime = estimateReadTime(postContent, { format: 'coffee' });

    return (
        <article className="prose">
            <div className="flex text-gray-500 gap-2">
                <span>Published Today</span>
                <span>•</span>
                <span>{readTime}</span> {/* Outputs: ☕ 5 min read */}
            </div>
            <div dangerouslySetInnerHTML={{ __html: postContent }} />
        </article>
    );
}

💚 Vue.js / Nuxt 3

<script setup>
import { computed } from 'vue';
import { estimateReadTime } from 'count-read-time';

const props = defineProps(['htmlContent']);

// Automatically recalculates if content changes
const readTime = computed(() => {
    return estimateReadTime(props.htmlContent, { format: 'hourglass' });
});
</script>

<template>
  <article>
    <p class="meta">{{ readTime }}</p> <!-- Outputs: ⏳ 5 mins -->
    <div v-html="htmlContent"></div>
  </article>
</template>

🧡 Svelte / SvelteKit

<script>
    import { estimateReadTime } from 'count-read-time';
    
    export let data; // Comes from your load function
    
    $: readTime = estimateReadTime(data.markdown, { format: 'standard' });
</script>

<header>
    <h1>{data.title}</h1>
    <p class="read-time">{readTime}</p> <!-- Outputs: 5 min read -->
</header>

🟢 Node.js / Express Backend

const express = require('express');
const { estimateReadTime } = require('count-read-time');

const app = express();

app.post('/api/articles', (req, res) => {
    const { content } = req.body;
    
    // Grab the raw exact seconds to save to your database
    const timeData = estimateReadTime(content, { format: 'raw' });
    database.saveArticle(content, timeData.seconds);
    
    res.json({ success: true, savedTime: timeData });
});

🟨 Vanilla JavaScript (Browser / CDN)

No bundler? No problem.

<script type="module">
    import { estimateReadTime } from 'https://unpkg.com/count-read-time';
    
    const blogText = document.getElementById('blog-content').innerText;
    const time = estimateReadTime(blogText, { format: 'coffee' });
    
    document.getElementById('read-time-display').innerText = time;
</script>

How It Works Under The Hood

We skipped messy, single-file code for a highly modular, $O(N)$ architecture:

  • src/parser.js: The heavy lifter. Uses pure Regex to safely strip formatting, count images universally, and separate code blocks from normal text. Returns $O(1)$ on empty strings.
  • src/calculator.js: A Pure Function that crunches the raw numbers.
  • src/formatter.js: The UI layer converting raw seconds into formatting strings.
  • index.js: The Orchestrator that safely routes data through a try/catch safety net.

The Testing Twist: We deleted our massive Jest testing frameworks to stay true to our zero-dependency philosophy. The library is rigorously tested via a raw, native Node.js script (tests/test.js) that directly attacks the parser with null inputs, malformed HTML, and massive strings to ensure it is virtually uncrashable.


License

This project is protected and licensed under the Apache License 2.0.