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

data-bionic-reading

v2.0.1

Published

Effortless bionic reading support for web content—improves readability by emphasizing approximately the first half of each word. Perfect for blogs, articles, and long-form content.

Readme

Bionic Reading

Effortless bionic reading support for web content—improves readability by emphasizing approximately the first half of each word. Perfect for blogs, articles, and long-form content.

View the demostration on CodePen.

Install

With a CDN

<script
  defer
  src="https://unpkg.com/data-bionic-reading@latest/dist/reading.min.js"
></script>

To customize options when using the CDN, set window.bionicReadingOptions before the script loads:

<script>
  window.bionicReadingOptions = {
    boldRatio: 0.6,
    minWordLength: 3,
  }
</script>

<script src="https://unpkg.com/data-bionic-reading@latest/dist/reading.min.js"></script>

(Note: The inline script executes immediately and sets the global options, then the CDN script loads and reads those options during initialization.)

With a Package Manager

yarn add -D data-bionic-reading
npm install -D data-bionic-reading
import bionicReading from 'data-bionic-reading'

document.addEventListener('DOMContentLoaded', () => {
  bionicReading()
})

Options

Out of the box, bionicReading() works with sensible defaults. You can customize behavior by passing an options object:

import bionicReading from 'data-bionic-reading'

document.addEventListener('DOMContentLoaded', () => {
  bionicReading({
    // targetSelector: '[data-bionic-reading]',
    // contentSelector: 'h1, h2, h3, h4, h5, h6, p, a, li, blockquote, figcaption, dt, dd',
    // excludeSelector: 'script, style, code, pre, kbd, samp, noscript',
    // minWordLength: 2,
    // boldRatio: 0.5,
    // baseFontWeight: 400,
    // processedAttribute: 'data-bionic-processed',
  })
})

(All shown above are defaults. Only pass options you wish to override.)

Option Details

  • targetSelector: Root elements to scan.
  • contentSelector: Content elements inside each target that are eligible.
  • excludeSelector: Elements that are never modified (useful for code blocks).
  • minWordLength: Shorter words are left untouched.
  • boldRatio: 0–1; how much of each word is bolded.
  • baseFontWeight: Applied to content elements (use null to skip).
  • processedAttribute: Attribute used to avoid double-processing.

Opt Out Per Section

If a specific block should not be processed, set:

<article data-bionic-reading="off"> ... </article>

Performance Tips

  • Limit scope by narrowing targetSelector.
  • Keep contentSelector focused on readable content, not layout wrappers.
  • If your app injects content dynamically, call bionicReading() only after the content is inserted, or pair it with a MutationObserver and requestAnimationFrame to batch updates per frame.
  • Warning: Observing document.body with subtree: true can cause performance issues on dynamic sites. Instead, observe only the specific container where content is injected to minimize unnecessary processing.

Accessibility

  • The library uses <strong> elements to emphasize portions of words. While semantically meaningful, some screen readers may announce "strong" or change voice tone, which could be distracting. Consider opening an issue if this is a concern for your use case.

MutationObserver Example

For dynamically injected content:

With a Package Manager:

import bionicReading from 'data-bionic-reading'

const applyBionicReading = () => bionicReading()

const contentObserver = new MutationObserver(() => {
  window.requestAnimationFrame(applyBionicReading)
})

// Observe a specific container instead of entire document.body for better performance
const contentContainer = document.getElementById('contentEl')

if (contentContainer) {
  contentObserver.observe(contentContainer, {
    childList: true,
    subtree: true,
  })
}

applyBionicReading()

With a CDN:

<script src="https://unpkg.com/data-bionic-reading@latest/dist/reading.min.js"></script>

<script>
  const applyBionicReading = () => {
    if (window.bionicReading) {
      window.bionicReading(window.bionicReadingOptions)
    }
  }

  const contentObserver = new MutationObserver(() => {
    window.requestAnimationFrame(applyBionicReading)
  })

  // Observe a specific container instead of entire document.body for better performance
  const contentContainer = document.getElementById('content')

  if (contentContainer) {
    contentObserver.observe(contentContainer, {
      childList: true,
      subtree: true,
    })
  }

  document.addEventListener('DOMContentLoaded', applyBionicReading)
</script>

Example

Note: The following example content is AI-generated for demonstration purposes.

<article data-bionic-reading>
  <h1>Why Bionic Reading Matters for Web Accessibility</h1>

  <p>
    Bionic reading is a technique that emphasizes the first half of each word,
    helping readers scan content faster and reduce cognitive load. By drawing
    attention to key letterforms, it creates a visual anchor that guides your
    eye through the text.
  </p>

  <p>
    This approach works especially well for people with dyslexia, ADHD, and
    other reading differences. Many modern websites now offer bionic reading as
    an <a href="#">accessibility feature</a> to improve user experience.
  </p>

  <h2>Benefits</h2>

  <ul>
    <li>Faster reading speed without sacrificing comprehension</li>
    <li>Reduced eye fatigue during extended reading sessions</li>
    <li>Better accessibility for neurodivergent users</li>
  </ul>
</article>