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

@3sv1n/react-lyrics

v0.1.2

Published

Headless hooks and components for syncing lyrics in React

Readme

@3sv1n/react-lyrics

Headless hooks and components for syncing and rendering LRC lyrics in React. Built on top of @3sv1n/lrc.

This package focuses entirely on the logic and structure of synchronized lyrics. It brings no opinions on styling, allowing you to integrate lyrics into any design system perfectly.

Installation

npm install @3sv1n/react-lyrics
# or
yarn add @3sv1n/react-lyrics
# or
pnpm add @3sv1n/react-lyrics

Note: This package requires react >= 18 as a peer dependency.

Basic Usage

Using the Unopinionated Component

SyncedLyrics handles the parsing, state management, and auto-scrolling of lyrics, but allows you to completely control the CSS classes and styles.

import { useState } from 'react';
import { SyncedLyrics } from '@3sv1n/react-lyrics';

const lrcString = `
[00:10.00]First line of the song
[00:15.50]Second line here
`;

function App() {
  const [currentTime, setCurrentTime] = useState(0);

  // In a real app, you would update currentTime from an audio player's state
  
  return (
    <div style={{ height: '300px', width: '400px' }}>
      <SyncedLyrics 
        lrc={lrcString}
        currentTime={currentTime}
        className="my-lyrics-container"
        lineClassName="lyric-line"
        activeLineClassName="lyric-line-active"
        passedLineClassName="lyric-line-passed"
        futureLineClassName="lyric-line-future"
        onSeek={(time) => console.log('User clicked lyric to seek to:', time)}
      />
    </div>
  );
}

Using the Headless Hook

If you need complete control over the DOM rendering, you can use the useSyncedLyrics hook.

import { useSyncedLyrics } from '@3sv1n/react-lyrics';

function CustomLyricsRenderer({ lrc, time }) {
  const { lines, activeIndex, activeLine, error } = useSyncedLyrics(lrc, time, {
    trimWhitespace: true,
    offset: 0 // Optional time offset in seconds
  });

  if (error) return <div>Error loading lyrics</div>;

  return (
    <ul>
      {lines.map((line, idx) => (
        <li 
          key={idx} 
          style={{ 
            fontWeight: idx === activeIndex ? 'bold' : 'normal',
            opacity: idx < activeIndex ? 0.5 : 1
          }}
        >
          {line.text}
        </li>
      ))}
    </ul>
  );
}

API Reference

SyncedLyrics (Component)

A scrolling container that renders parsed LRC lyrics.

Props:

  • lrc: string - The raw LRC text content.
  • currentTime: number - Current playback time in seconds.
  • fallbackContent?: React.ReactNode - Content to render if lyrics are missing.
  • onSeek?: (time: number) => void - Callback fired when a user clicks on a lyric line.
  • autoScroll?: boolean - Whether to automatically scroll the active line into view (default: true).
  • offset?: number - Global offset in seconds to apply to the LRC timestamps.
  • trimWhitespace?: boolean - Whether to trim whitespace from lyric lines.

Styling Props:

  • className?: string - CSS class for the scrolling container.
  • style?: React.CSSProperties - Inline styles for the container.
  • lineClassName?: string - Base CSS class applied to every line.
  • activeLineClassName?: string - CSS class applied only to the currently active line.
  • passedLineClassName?: string - CSS class applied to lines that have already passed.
  • futureLineClassName?: string - CSS class applied to upcoming lines.

useSyncedLyrics(lrcContent, currentTime, options) (Hook)

Options:

  • offset?: number
  • trimWhitespace?: boolean

Returns:

{
  lines: LyricLine[];         // Array of parsed lyric lines
  activeIndex: number;        // The index of the active line (-1 if none)
  activeLine: LyricLine | null; // The active line object
  error?: Error;              // Any parsing errors
}