react-joyride

A React component and hook for building guided product tours with spotlight overlays and floating tooltips.

Library
npm
v3.2.0
7,856stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
68/100Good
Development Activity44
Maintenance68
Community60
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
89/100Excellent
Architecture92
Code Quality90
Innovation85
Learning Curve90

react-joyride lets you script step-by-step walkthroughs of a React app by pointing at existing DOM elements — no redesign of the UI required. Each step spotlights a target with an animated beacon, then opens a positioned tooltip with back/next/skip controls, driven by a small internal state machine that tracks tour status and per-step lifecycle separately.

Both a <Joyride> component and a useJoyride() hook expose the same engine, so teams can either drop in a fully rendered tour or wire the state into their own UI via the onEvent callback. Controlled and uncontrolled modes are both supported: uncontrolled tours auto-advance internally, while controlled tours pause at each step and let the parent decide when to move on — useful for tours gated on async data or route changes.

Under the hood it uses Floating UI for tooltip/beacon positioning (with automatic flip/shift and scroll-into-view), a focus trap for keyboard accessibility, and per-step before/after hooks with timeouts for async setup. The library ships as ESM/CJS with bundled types and works across React 16.8 through 19, including SSR frameworks like Next.js and Remix.

What You Get

  • A <Joyride> component and an equivalent useJoyride() hook, both backed by the same tour engine and returning the same controls/state/events shape
  • Controlled mode (parent owns stepIndex) and uncontrolled mode (internal auto-advance), selected simply by whether stepIndex is passed
  • Floating UI-based positioning for tooltips and beacons with flip/shift/arrow middleware, plus automatic scroll-into-view for off-screen targets
  • A single onEvent(data, controls) callback surfacing a well-defined event stream (tour:start, step:before, beacon, tooltip, step:after, tour:end, error:target_not_found, etc.)
  • Per-step before/after async hooks with configurable timeouts, so a step can fetch data or wait on a condition before its target is highlighted
  • Full customization points — custom Beacon/Tooltip/Arrow/Loader components, style overrides, and a portalElement target for rendering inside a specific container

Common Use Cases

  • Onboarding walkthroughs that introduce new users to a dashboard’s key features on first login
  • Feature-announcement tours that point out newly shipped UI after a release
  • Guided setup flows that walk a user through a multi-step configuration screen, waiting on async validation between steps
  • In-app help overlays triggered from a “Take a tour” button rather than shown automatically
  • Coordinating a tour with app state (e.g. pausing on a step until a modal opens) using controlled mode plus the onEvent callback

Under The Hood

Architecture The engine is layered around a plain-object Store class (src/modules/store.ts) that holds frozen state snapshots and notifies subscribers on change; useTourEngine creates one store per component instance via useRef and subscribes through useSyncExternalStore, so React re-renders stay in sync with an update source that lives outside React’s own state. Above the store, useTourEngine delegates to five focused sub-hooks (useControls, useEventEmitter, usePropSync, useLifecycleEffect, useScrollEffect) that each own one concern — control methods, event emission, external prop syncing, state-machine progression, and scroll-to-target — rather than one large effect. useLifecycleEffect alone runs five separate effects to drive a documented two-dimensional state machine (overall tour status plus per-step lifecycle phase), which the project’s own docs/architecture.md diagrams in full. The public surface is intentionally thin: useJoyride wraps the engine, strips the internal positioned flag, and returns a TourRenderer element, while the <Joyride> component is just an SSR guard around that hook.

Tech Stack Written in TypeScript and built with tsdown to dual ESM/CJS output with bundled .d.ts files, targeting React 16.8 through 19 as a peer dependency. Positioning is delegated to @floating-ui/react-dom (two independent useFloating() instances for tooltip and beacon), scrolling to the scroll/scrollparent packages, and prop merging/equality to @fastify/deepmerge and @gilbarbara/deep-equal. A handful of small @gilbarbara/* utility packages (hooks, types) supply shared helpers the same author maintains elsewhere. There’s no runtime state library or CSS framework dependency — styling is generated in src/styles.ts and injected directly.

Code Quality Every module and hook under src/ has a matching spec file in test/ (store, step merging, DOM helpers, each hook individually), run under Vitest with coverage, plus a full Playwright e2e suite exercising real browser interactions and a separate website/ app used as the e2e fixture target. CI (pnpm validate) runs lint, typecheck, unit tests with coverage, @arethetypeswrong/cli type-validation, bundle size limits, and SonarCloud static analysis on every push, and the after step hook and event dispatch are explicitly wrapped in try/catch so consumer callback errors can’t crash the tour. Naming and typing are consistent and strict throughout, with no untyped any escape hatches observed in the core engine.

API Design Offering both a component and a hook that share one engine (and one return shape) lets consumers pick between a drop-in tour or full control over rendering, with controlled/uncontrolled mode selected implicitly by whether stepIndex is passed rather than a separate prop. The single onEvent(data, controls) callback consolidates what other tour libraries often split across many individual callbacks, and passing controls alongside event data lets a handler call next()/stop() directly without holding a separate ref. Getting started requires only a steps array with target/content pairs, with every other option — hooks, custom components, floating behavior — layered on as opt-in.

Used by 8 apps in this directory

TypeScript
53%
Apache 2.0

Flowsint

Automation · Developer Tools

7,800

A privacy-first, graph-based OSINT investigation platform with 30+ automated enrichers for mapping relationships between domains, IPs, people, and organizations.

View details
85
Repo Health
71
Technical
70
Dependency
Built with
TypeScript53%
Python44%
Updated yesterday
TypeScript
98%
Other

Hexabot

AI Development · Automation

1,213

Build and run agentic workflows across channels with YAML, tools, and RAG

View details
77
Repo Health
76
Technical
65
Dependency
Built with
TypeScript98%
Updated 2 weeks ago
TypeScript
38%
Apache 2.0

Label Studio

AI Development · Data Engineering

28,222

Label Studio is an open-source, multi-type data labeling platform that lets teams annotate images, text, audio, video, and time series data with a configurable XML-based UI and export annotations in formats ready for any ML framework.

View details
93
Repo Health
87
Technical
67
Dependency
Built with
TypeScript38%
JavaScript27%
Python25%
Updated today
TypeScript
94%
AGPL 3.0

Laudspeaker

Marketing · Automation

2,620

Open-source customer engagement platform for building visual, event-triggered messaging journeys across email, SMS, push, in-app, and webhooks.

View details
51
Repo Health
66
Technical
62
Dependency
Built with
TypeScript94%
Updated 1 months ago
JavaScript
44%
Other

LimeSurvey

Forms Surveys

3,711

The world's most flexible open-source survey platform with 900+ templates, conditional logic, 80+ languages, and full GDPR compliance for any scale.

View details
85
Repo Health
62
Technical
62
Dependency
Built with
JavaScript44%
PHP34%
CSS12%
Updated 2 days ago
TypeScript
88%
MIT

Plasmic

CMS · Low Code Platforms · No Code Platforms

6,993

The open-source visual builder that lets teams design React apps and websites with drag-and-drop while integrating seamlessly with your codebase.

View details
81
Repo Health
78
Technical
64
Dependency
Built with
TypeScript88%
Updated yesterday
TypeScript
99%
Other

Teable

Databases · No Code Platforms

21,759

A no-code PostgreSQL database with spreadsheet UX, real-time collaboration, and native AI agents — built for teams that outgrow Airtable.

View details
79
Repo Health
76
Technical
63
Dependency
Built with
TypeScript99%
Updated today
TypeScript
97%
Apache 2.0

Unleash

Developer Tools · Devops · Ab Testing Experimentation

13,787

The open-source feature management platform that lets you ship code to production and control who sees it — without redeploying.

View details
91
Repo Health
84
Technical
70
Dependency
Built with
TypeScript97%
Updated today

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

Search