react-tooltip

A lightweight, accessible React tooltip component with automatic Floating UI-powered positioning.

Library
npm
v6.0.9
3,826 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
78 /100 Good
Development Activity 68
Maintenance 72
Community 72
Maturity 60
Momentum 40

Technical Analysis

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

React Tooltip is a customizable tooltip component for React applications. It lets you attach contextual popovers to any DOM element through simple data-tooltip-* attributes or an imperative React API, renders through a portal, and supports rich HTML/JSX content or plain text. Positioning is computed automatically using Floating UI middleware (flip, shift, arrow) so tooltips reposition themselves to stay within the viewport regardless of where the anchor sits on the page.

Now in its v6 release, the library supports React 16.14 through 19, including apps using React Server Components (the Tooltip itself must render inside a client boundary). It ships a shared document-level event delegation system that keeps listener counts low even with many tooltips on one page, plus controlled and uncontrolled visibility modes, configurable show/hide delays, click-to-open behavior, and a render prop for building tooltip content dynamically from the active anchor.

What You Get

  • Declarative <Tooltip> component with a data-tooltip-id/data-tooltip-content attribute API for zero-boilerplate usage
  • Floating UI-powered positioning with automatic flip/shift/arrow middleware to keep tooltips on-screen
  • Controlled and uncontrolled visibility modes via isOpen/setIsOpen or built-in open/close event handling
  • A render prop for fully custom tooltip content driven by the active anchor element
  • Shared document-level event delegation so many tooltips on one page stay cheap in listener count
  • Full TypeScript typings shipped in the package (dist/react-tooltip.d.ts)

Common Use Cases

  • Icon-only UI buttons that need an accessible text label on hover/focus
  • Form field help text and validation hints shown next to inputs
  • Dashboard and data-table cells with truncated values that reveal the full value on hover
  • Onboarding/product tours that point out a specific control with contextual copy
  • Disabled-button explanations telling users why an action isn’t available

Under The Hood

Architecture

The public Tooltip export (TooltipController.tsx) is a thin normalization layer: it reads live data-tooltip-* attributes off the currently active anchor (tracked via anchor-registry.ts and a MutationObserver-based shared-attribute-observer.ts), merges them over the component’s props with data-attributes taking priority, and hands the resolved config down to the inner Tooltip component. Positioning is delegated to compute-tooltip-position.ts, a wrapper around @floating-ui/dom’s computePosition with hoisted flip/shift middleware and an optional arrow middleware. A separate event-delegation.ts module maintains exactly one document-level listener per event type/capture-phase combination and fans events out to all registered tooltip instances, turning what would be O(N tooltips x M event types) listeners into O(M). The three concerns — anchor tracking, position math, and global event plumbing — are cleanly separated into their own modules.

Tech Stack

Written in TypeScript against React 19 (peer range >=16.14.0 for both react and react-dom), with only two runtime dependencies: @floating-ui/dom for position computation and clsx for conditional class names. The build pipeline uses esbuild for the dev server (esbuild.config.dev.mjs) and Rollup for production (rollup.config.prod.mjs, rollup-plugin-dts for bundled type declarations, rollup-plugin-terser for minification, rollup-plugin-postcss for CSS Modules), publishing dual CJS/ESM builds through a conditional exports map. A prebuild.js script performs environment-specific codegen before bundling.

Code Quality

The src/test/ directory holds an extensive Jest suite (13+ spec files covering interactions, controlled/ref usage, imperative APIs, observers, styling, attribute resolution, and edge cases), run under jest-environment-jsdom with @testing-library/react and coverage collected via the V8 provider. Linting combines eslint-config-airbnb, eslint-plugin-jsx-a11y, and eslint-plugin-react-hooks, enforced through Husky pre-commit hooks and lint-staged, with CI configured via both .travis.yml and GitHub Actions workflows.

What Makes It Unique

The shared document-level event delegation system is a comprehensive alternative to the more common per-instance listener pattern seen in similar tooltip libraries, keeping pages with many simultaneous tooltips lighter on memory and event-dispatch overhead. Beyond that, the library’s core interaction model — resolving tooltip behavior from live DOM data-attributes rather than requiring a JS-side configuration object per anchor — is a well-executed but by-now standard pattern within the React tooltip ecosystem rather than a genuinely novel technique.

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