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 🙏

© 2025 – Pkg Stats / Ryan Hefner

scrimr

v2.2.4

Published

🎲 A simple React shimmer component that displays animated random text while loading. Lightweight alternative to skeleton screens.

Readme

Scrimr

npm version License: MIT TypeScript

🎲 A simple React shimmer component that displays animated random text while loading. Lightweight alternative to skeleton screens.

✨ Features

  • 🎲 Animated Random Text - Continuously changing random characters during loading
  • Ultra Lightweight - Only ~84 lines of code, 1.65KB ESM bundle
  • 🎯 Simple API - Just 5 props to control everything
  • ✂️ Text Truncation - Built-in support for single-line text with ellipsis
  • 🎨 Tailwind Compatible - Works seamlessly with Tailwind CSS classes
  • 🎯 TypeScript Support - Fully typed for better developer experience
  • 📦 Zero Config - Works out of the box with sensible defaults

Installation

npm install scrimr
# or
yarn add scrimr
# or
pnpm add scrimr

🚀 Quick Start

import { useState } from 'react'
import { Scrimr } from 'scrimr'

function MyComponent() {
  const [isLoading, setIsLoading] = useState(true)
  
  return (
    <Scrimr isLoading={isLoading}>
      Hello, World!
    </Scrimr>
  )
}

📚 API Reference

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | isLoading | boolean | required | Controls loading state | | children | React.ReactNode | required | Content to display when not loading | | length | number | 20 | Length of placeholder text | | speed | number | 100 | Update interval in milliseconds | | chars | string | Mixed set | Custom character set for random text | | className | string | - | Additional CSS classes |

Default Character Set

The default character set includes:

  • Letters: a-z, A-Z
  • Numbers: 0-9
  • Symbols: !@#$%^&*
  • Spaces for realistic text appearance

Examples

Basic Usage

<Scrimr isLoading={isLoading}>
  Your content here
</Scrimr>

Custom Length and Speed

<Scrimr 
  isLoading={isLoading}
  length={30}
  speed={50}
>
  Longer text with faster animation
</Scrimr>

Custom Character Set

{/* Numbers only */}
<Scrimr 
  isLoading={isLoading}
  length={8}
  chars="0123456789"
>
  $1,234.56
</Scrimr>

{/* Custom text */}
<Scrimr 
  isLoading={isLoading}
  length={12}
  chars="LOADING."
>
  Please wait...
</Scrimr>

Text Truncation

The component includes built-in truncate support. Just set a width on the parent container:

{/* Container with width constraint */}
<div className="w-48">
  <Scrimr isLoading={isLoading} length={50}>
    This is a very long text that will be truncated with ellipsis
  </Scrimr>
</div>

Styled Examples

{/* Title */}
<h1 className="text-2xl font-bold">
  <Scrimr isLoading={isLoading} className="text-blue-600">
    Page Title
  </Scrimr>
</h1>

{/* Button */}
<button className="bg-blue-500 text-white px-4 py-2 rounded">
  <Scrimr isLoading={isLoading} length={8}>
    Submit
  </Scrimr>
</button>

{/* Paragraph */}
<p className="text-gray-700">
  <Scrimr isLoading={isLoading} length={40} speed={80}>
    This is a paragraph of text that shows how Scrimr works in longer content.
  </Scrimr>
</p>

Loading States

function DataComponent() {
  const [isLoading, setIsLoading] = useState(true)
  const [data, setData] = useState(null)

  useEffect(() => {
    fetchData().then(result => {
      setData(result)
      setIsLoading(false)
    })
  }, [])

  return (
    <div>
      <Scrimr isLoading={isLoading}>
        {data?.title}
      </Scrimr>
    </div>
  )
}

Why Scrimr?

vs. Skeleton Screens

  • More Engaging: Dynamic text is more interesting than static gray boxes
  • Context Aware: Shows text-like content instead of generic shapes
  • Smaller Bundle: No complex skeleton layouts needed
  • Flexible: Works with any text content automatically

vs. Other Libraries

  • Simpler: Just 5 props vs. dozens of configuration options
  • Lighter: 1.65KB vs. 10KB+ for most alternatives
  • Focused: Does one thing well instead of trying to do everything
  • Modern: Built with modern React patterns and TypeScript

Tailwind CSS

Scrimr works perfectly with Tailwind CSS. The component uses cn() utility for class merging:

<Scrimr 
  isLoading={isLoading}
  className="text-green-500 font-mono text-lg"
>
  System Status: Online
</Scrimr>

TypeScript

Scrimr is built with TypeScript and provides full type safety:

interface ScrimrProps {
  isLoading: boolean
  children: React.ReactNode
  length?: number
  speed?: number
  chars?: string
  className?: string
}

Bundle Size

  • ESM: 1.65KB
  • CJS: 2.83KB
  • Dependencies: Only clsx and tailwind-merge

Browser Support

Scrimr works in all modern browsers that support:

  • ES2022+
  • React 19+
  • CSS animations

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Changelog

v2.2.4

  • Upgraded to React 19 support
  • Updated TypeScript target to ES2022
  • Maintained full backward compatibility

v2.2.2

  • Fixed npm package repository links
  • Updated repository URL from reihuang/scrimr to reidevbx/scrimr

v2.2.1

  • Improved performance with speed parameter adjustments
  • Enhanced user experience with refined speed ranges and display text
  • Updated demo project dependencies

v2.2.0

  • Added partialUpdateRatio parameter for smoother animations
  • Added placeholderLabel parameter for accessibility support
  • Added prefers-reduced-motion system preference support
  • Auto-pause animations when tab is hidden for performance
  • Precise width control using minWidth: ${length}ch
  • Full ARIA attributes support
  • Optimized timer management and memory usage

v2.1.0

  • Added built-in text truncation support
  • Improved container width handling
  • Enhanced demo examples

v2.0.0

  • Complete rewrite for simplicity
  • Reduced from 1000+ lines to ~84 lines
  • Simplified API to 5 essential props
  • Removed complex state management
  • 80% smaller bundle size