react-popper

Official React bindings for Popper, the positioning engine behind tooltips, popovers, and dropdowns

Library
npm
v2.3.0
2,485 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
48 /100 Fair
Development Activity 0
Maintenance 32
Community 60
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
66 /100 Good
Architecture 68
Code Quality 70
Innovation 55
Learning Curve 72

react-popper is the official React wrapper around Popper.js, exposing its viewport-aware positioning engine as a usePopper() hook (plus legacy Manager/Reference/Popper render-prop components) so React components can position a floating element — a tooltip, dropdown, or popover — relative to a reference element without re-implementing collision detection, flipping, or offset math.

What You Get

  • A usePopper(referenceElement, popperElement, options) hook returning computed styles and attributes to spread onto your floating element
  • Automatic recalculation of position on scroll, resize, and reference-element mutation via Popper’s built-in observers
  • Legacy Manager/Reference/Popper render-prop components for class-component or pre-hooks codebases
  • Full access to the underlying Popper.js options (placement, modifiers like flip, offset, preventOverflow) for fine-grained positioning control

Common Use Cases

  • Building a custom tooltip component that stays attached to its trigger element and flips when it would overflow the viewport
  • Implementing a dropdown menu or select component that positions its panel relative to the trigger button
  • Creating a popover or context-menu component that needs collision-aware placement instead of fixed absolute positioning
  • Powering the positioning layer underneath a design-system component library that ships its own tooltip/dropdown/popover primitives

Under The Hood

Architecture The library’s modern API is a single hook, usePopper.js (157 lines), which instantiates a Popper.js instance via createPopper() from @popperjs/core, subscribes to its state updates, and returns memoized styles/attributes objects that the consumer spreads onto their floating element’s props — Popper itself owns all positioning math (Popper.js in @popperjs/core), while this package is purely a thin React lifecycle adapter. The legacy Manager/Reference/Popper components (Manager.js, Reference.js, Popper.js) implement the same wrapping via React context and render props for pre-hooks consumers. Tech Stack JavaScript (with Flow type annotations, __typings__) built via Babel to separate ESM and CJS outputs plus a Rollup-built UMD bundle, depending directly on @popperjs/core for all positioning logic; the package itself contains no positioning algorithm code. Code Quality Each core module has a matching Jest test file with snapshot coverage (Popper.test.js, Manager.test.js, Reference.test.js, usePopper.test.js), giving solid coverage of the wrapping layer’s behavior, though the project has had no commits since 2024 and does not yet ship first-class TypeScript declarations (relying on community @types/react-popper instead). API Design The usePopper hook API is intentionally minimal — pass in two DOM refs and get back a styles/attributes pair to spread onto your element — which fits naturally into React’s declarative model, though because it’s a thin pass-through to Popper.js, understanding its modifier options still requires reading Popper’s own (separate) documentation.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers