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

react-use-fittext

v1.0.2

Published

React hook to automatically adjust font size to fit text in its container

Readme

react-use-fittext

A powerful React hook that automatically adjusts font size to fit text within its container. Perfect for responsive typography that scales beautifully across different screen sizes and container dimensions.

npm version License: MIT

✨ Features

  • 📏 Automatic font sizing - Text scales to fit perfectly within container bounds
  • 🔄 Responsive by default - Uses ResizeObserver for real-time container changes
  • ⚡️ High performance - Optimized with requestAnimationFrame and binary search algorithm
  • 📐 Flexible fit modes - Fit to width, height, or both dimensions
  • 📝 Multi-line support - Works seamlessly with single-line and multi-line text
  • ⏱️ Debounced updates - Configurable debounce for smooth performance
  • 🎯 TypeScript support - Fully typed with comprehensive type definitions
  • 🪶 Lightweight - Minimal bundle size with zero dependencies

📦 Installation

npm install react-use-fittext
yarn add react-use-fittext
pnpm add react-use-fittext

🚀 Quick Start

import { useFitText } from 'react-use-fittext';

function ResponsiveText() {
  const { containerRef, textRef, fontSize } = useFitText();

  return (
    <div 
      ref={containerRef} 
      style={{ 
        width: '300px', 
        height: '200px', 
        border: '1px solid #ccc',
        padding: '16px'
      }}
    >
      <div ref={textRef}>
        This text will automatically resize to fit!
      </div>
    </div>
  );
}

📖 Advanced Examples

Single Line Text

function SingleLineExample() {
  const { containerRef, textRef } = useFitText({
    lineMode: 'single',
    minFontSize: 12,
    maxFontSize: 60
  });

  return (
    <div ref={containerRef} className="banner">
      <h1 ref={textRef}>BREAKING NEWS</h1>
    </div>
  );
}

Fit Width Only

function WidthOnlyExample() {
  const { containerRef, textRef } = useFitText({
    fitMode: 'width',
    maxFontSize: 48
  });

  return (
    <div ref={containerRef} style={{ width: '100%', maxWidth: '600px' }}>
      <p ref={textRef}>
        This text will scale based on container width only,
        allowing vertical overflow if needed.
      </p>
    </div>
  );
}

Performance Optimized

function PerformanceExample() {
  const { containerRef, textRef, fontSize } = useFitText({
    debounceDelay: 50,      // Faster response
    resolution: 1,         // Higher precision
    minFontSize: 8,
    maxFontSize: 120
  });

  return (
    <div ref={containerRef} className="dynamic-container">
      <span ref={textRef}>
        Current font size: {fontSize}px
      </span>
    </div>
  );
}

Dynamic Content

function DynamicContentExample() {
  const [text, setText] = useState('Initial text');
  const { containerRef, textRef } = useFitText({
    fitMode: 'both',
    debounceDelay: 100
  });

  return (
    <div>
      <input 
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="Type to see text resize..."
      />
      
      <div ref={containerRef} className="text-container">
        <div ref={textRef}>{text}</div>
      </div>
    </div>
  );
}

📚 API Reference

useFitText(options?)

Options

| Property | Type | Default | Description | |----------|------|---------|-------------| | minFontSize | number | 1 | Minimum font size in pixels | | maxFontSize | number | 100 | Maximum font size in pixels | | resolution | number | 0.5 | Precision of the binary search algorithm (lower = more precise) | | fitMode | 'width' \| 'height' \| 'both' | 'both' | Which dimensions to fit the text into | | lineMode | 'single' \| 'multi' | 'multi' | Whether to allow text wrapping | | debounceDelay | number | 100 | Debounce delay in milliseconds for resize events |

Return Value

| Property | Type | Description | |----------|------|-------------| | containerRef | RefObject<HTMLElement> | Attach to the container element | | textRef | RefObject<HTMLElement> | Attach to the text element | | fontSize | number | Current calculated font size in pixels |

🎛️ Fit Modes

'both' (default)

Text scales to fit within both width and height constraints of the container.

'width'

Text scales based only on container width. Height can grow as needed.

'height'

Text scales based only on container height. Width can grow as needed.

📝 Line Modes

'multi' (default)

Allows text to wrap across multiple lines. Text will break naturally at word boundaries.

'single'

Forces text to remain on a single line. Long text will be truncated with ellipsis if it exceeds container width.

⚡ Performance Tips

  1. Adjust debounceDelay - Lower values (50-100ms) for faster response, higher values (200-300ms) for better performance
  2. Tune resolution - Use 1 for pixel-perfect sizing, 0.5 for good balance, 2-3 for faster calculations
  3. Choose appropriate fitMode - Use 'width' or 'height' instead of 'both' when you only need single-axis fitting
  4. Set reasonable bounds - Use minFontSize and maxFontSize to prevent extreme scaling

🔧 Common Patterns

Card Titles

const { containerRef, textRef } = useFitText({
  lineMode: 'single',
  fitMode: 'width',
  minFontSize: 14,
  maxFontSize: 24
});

Hero Banners

const { containerRef, textRef } = useFitText({
  fitMode: 'both',
  minFontSize: 32,
  maxFontSize: 96,
  debounceDelay: 50
});

Responsive Labels

const { containerRef, textRef } = useFitText({
  lineMode: 'single',
  fitMode: 'width',
  minFontSize: 10,
  maxFontSize: 16
});

🐛 Troubleshooting

Text not resizing?

  • Ensure the container has defined dimensions (width/height)
  • Check that both containerRef and textRef are properly attached
  • Verify the container is visible in the DOM

Performance issues?

  • Increase debounceDelay to reduce calculation frequency
  • Increase resolution for faster (but less precise) calculations
  • Consider using fitMode: 'width' or 'height' instead of 'both'

Text overflowing?

  • Check that container has overflow: hidden if needed
  • Ensure minFontSize isn't too large for the container
  • Verify container padding is accounted for in your layout

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

📄 License

MIT © akozma89