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

@tanem/react-nprogress

v7.1.2

Published

A React primitive for building slim progress bars.

Downloads

1,063,540

Readme

react-nprogress

npm version build status coverage status npm downloads minzipped size

A React primitive for building slim progress bars.

Background | When to Use This | Usage | API | Live Examples | Installation | Contributing | License

Background

This is a React port of rstacruz's nprogress module. It exposes an API that encapsulates the logic of nprogress and renders nothing, allowing consumers to implement their own rendering.

Two versions of nprogress are in circulation and they trickle differently. The 2014 npm release, 0.2.0, adds a random amount of at most 0.02 every 800ms. The repository's master branch, never published to npm, adds tiered amounts every 200ms. This library mirrors master, so a side by side comparison against the npm package or the official demo page will show a different pace. The increment option covers the 0.2.0 pacing if you prefer the older feel.

When to Use This

This package is a headless primitive. It renders no markup and ships no CSS, supplying only the pacing state: a progress value that trickles towards completion, an isFinished flag, and the animationDuration to transition with. The bar itself is yours to write.

  • Use a drop-in bar such as nextjs-toploader, next-nprogress-bar, or nprogress itself when you want a styled bar wired up to your router with no rendering work.
  • Use this package when you render the bar yourself, for example with design-system components or custom containers and spinners, and want only the trickle and completion logic handled for you.
  • Use this package when you need several progress bars on one page, each tracking its own state.

Usage

Container, Bar and Spinner are components you write: this package renders nothing itself. Every entry in Live Examples contains a working implementation of all three.

Hook

import { useNProgress } from '@tanem/react-nprogress'

import Bar from './Bar'
import Container from './Container'
import Spinner from './Spinner'

const Progress = ({ isAnimating }) => {
  const { animationDuration, isFinished, progress } = useNProgress({
    isAnimating,
  })

  return (
    <Container animationDuration={animationDuration} isFinished={isFinished}>
      <Bar animationDuration={animationDuration} progress={progress} />
      <Spinner />
    </Container>
  )
}

Render Props

import { NProgress } from '@tanem/react-nprogress'

import Bar from './Bar'
import Container from './Container'
import Spinner from './Spinner'

const Progress = ({ isAnimating }) => (
  <NProgress isAnimating={isAnimating}>
    {({ animationDuration, isFinished, progress }) => (
      <Container animationDuration={animationDuration} isFinished={isFinished}>
        <Bar animationDuration={animationDuration} progress={progress} />
        <Spinner />
      </Container>
    )}
  </NProgress>
)

Restarting

Both patterns leave the bar mounted between runs, and progress returns to minimum when it starts again. A bar that transitions margin-left or transform therefore animates backwards from where it finished, in full view, before it starts trickling forward. Back to back navigations hit this every time.

Change a key on the bar whenever it starts, so React mounts a fresh element at minimum instead:

const [state, setState] = useState({ isAnimating: false, key: 0 })

const start = () => {
  setState((prevState) => ({ isAnimating: true, key: prevState.key ^ 1 }))
}

return <Progress isAnimating={state.isAnimating} key={state.key} />

Every entry in Live Examples does this. Dropping the transition while isFinished is not an alternative: isFinished is already false by the time progress resets, so the transition is back on for the step that moves the bar.

API

The package exports one hook and one component. Both take the same options and produce the same values, so the choice between them is a matter of which pattern suits the calling code. Both shapes are exported as types, for typing code that wraps either entry point:

import type { NProgressOptions, NProgressState } from '@tanem/react-nprogress'

useNProgress

Returns the state of one progress bar. Call it once per bar: two calls, or two mounted NProgress components, track their progress independently.

const { animationDuration, isFinished, progress } = useNProgress({
  animationDuration: 300,
  increment: (progress) => progress + 0.01,
  incrementDuration: 500,
  isAnimating: true,
  minimum: 0.1,
})

NProgress

Takes the options as props and calls children with the values the hook returns. children is required and must return a React element.

<NProgress
  animationDuration={300}
  increment={(progress) => progress + 0.01}
  incrementDuration={500}
  isAnimating
  minimum={0.1}
>
  {({ animationDuration, progress }) => (
    <Bar animationDuration={animationDuration} progress={progress} />
  )}
</NProgress>

Options

All five options are optional. The type is NProgressOptions.

| Option | Type | Default | | ----------------------------------------- | ------------------------------ | -------------- | | animationDuration | number | 200 | | increment | (progress: number) => number | tiered trickle | | incrementDuration | number | 200 | | isAnimating | boolean | false | | minimum | number | 0.08 |

animationDuration

Milliseconds the bar is given to animate out once it completes. progress reaches 1 as soon as isAnimating goes false, and isFinished follows this many milliseconds later, leaving that window for the exit transition. The value is also returned unchanged, so a single number drives both the timing and the CSS transitions.

increment

Size of each trickle step. The function is called with the current progress and returns the next value. The default is the tiered curve nprogress uses: +0.1 below 0.2, then +0.04, +0.02, and +0.005 as progress grows, held at a ceiling of 0.994 so the bar never looks complete before it is.

The return value is clamped to between minimum and 1, and nothing else. A custom function therefore owns its own ceiling. Leave it short of 1, since reaching 1 is what completion means, and let isAnimating going false take the bar the rest of the way.

Returning a random amount is fine, but keep the function free of other side effects. It runs inside a React state update, and StrictMode calls it twice per increment in development. This trickles a random amount of at most 0.02 every 800ms, which is how nprogress 0.2.0 paces itself:

const { progress } = useNProgress({
  increment: (progress) => Math.min(progress + Math.random() * 0.02, 0.994),
  incrementDuration: 800,
  isAnimating,
})

0.2.0 also transitions the bar with ease where master uses linear. Easing lives in your renderer's CSS, so match it there if you want the rest of that look. The Classic 0.2.0 example puts both together.

A new function identity on every render is fine too: passing an inline function does not restart the trickle timer. The next increment uses the latest function.

incrementDuration

Milliseconds between increments while the bar is animating. It controls the trickle pacing only. Step size is increment.

isAnimating

Whether the bar is running. Going true starts it, going false completes it. Completion is what drives the final state: progress is set to 1, and isFinished becomes true animationDuration milliseconds later.

minimum

Lower bound for progress, between 0 and 1. The bar first appears at this value, then trickles up from there. Changing it while the bar is animating does not rewind the bar. Progress holds where it is, and the new bound applies from the next increment.

Return Value

useNProgress returns these values, and NProgress passes the same object to children. The type is NProgressState.

| Value | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | animationDuration | number | The animationDuration option, passed through so rendering code can transition with it. | | isFinished | boolean | true before the bar starts and again once it has animated out. false from when isAnimating goes true until animationDuration after it goes false. | | progress | number | Starts at 0, appears at minimum when the bar starts, then trickles up by increment and goes to 1 on completion. |

Live Examples

| Example | Sandbox | | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | | Classic 0.2.0 | Open | | Material UI | Open | | Multiple Instances | Open | | Next App Router | Open | | Next Pages Router | Open | | Original Design | Open | | Plain JS | Open | | React Router | Open | | Render Props | Open |

Installation

$ npm install @tanem/react-nprogress

Contributing

Issues and pull requests are welcome. The development loop is npm run test:src, and npm test runs the full suite. Repository conventions, for humans and coding agents alike, live in AGENTS.md.

License

MIT