Skip to main content
userTourKit
Codemods

from-joyride

Migrate a React Joyride v2 codebase to Tour Kit with the tour-kit-migrate --from joyride codemod.

domidex01Published

Rewrites the react-joyride imports plus both the legacy <Joyride> JSX form and the modern useJoyride() hook form. Joyride's step shape ({ target, content }) already matches Tour Kit, so step lists carry over unchanged.

Run

npx tour-kit-migrate --from joyride --dry-run ./src
npx tour-kit-migrate --from joyride ./src

Run with --dry-run to preview the diff without writing. Run with --print to write transformed source to stdout. Add --verbose to log every file action.

What it changes

React JoyrideTour Kit
import Joyride from 'react-joyride'import { TourProvider } from '@tour-kit/react'
import { useJoyride } from 'react-joyride'import { useTour } from '@tour-kit/react'
<Joyride steps={...} /><TourProvider tours={[{ id: 'migrated-tour', steps }]} />
{ target: '.x', content: '...' }same shape — no change
const { Tour, controls } = useJoyride({ steps })const controls = useTour() + // TODO: to register the tour
<Tour />null + // TODO: to render via a <TourProvider> ancestor

What it does NOT handle

  • Joyride-only props (callback, run, stepIndex, showProgress, showSkipButton, continuous, disableBeacon, …) are preserved next to the output with a // TODO: linking to the matching anchor in the React Joyride migration guide. For example continuous is the default in Tour Kit and can be dropped, while run maps to calling useTour().start().
  • Step.styles / Step.tooltipComponent — custom tooltip rendering ports to <TourCard> children, not a prop.
  • useJoyride control wiring. The hook is swapped for useTour(), but registering the tour at a <TourProvider> ancestor is left as a // TODO:.

Example

Before:

import Joyride from 'react-joyride'

function App() {
  return (
    <Joyride
      steps={[
        { target: '.step-1', content: 'Welcome!' },
        { target: '.step-2', content: 'Next up.' },
      ]}
      run
      continuous
    />
  )
}

After codemod:

import { TourProvider } from '@tour-kit/react'

function App() {
  return (
    <TourProvider
      tours={[
        {
          id: 'migrated-tour',
          steps: [
            { target: '.step-1', content: 'Welcome!' },
            { target: '.step-2', content: 'Next up.' },
          ],
        },
      ]}
      // TODO: `run` had no direct prop — call useTour().start() to begin.
      // /docs/migration/joyride#run
      // TODO: `continuous` is the Tour Kit default — drop it.
      // /docs/migration/joyride#continuous
    />
  )
}

See also

Free & open source

Ship onboarding, not config.

npm i @tour-kit/core is MIT and free. The Pro packages work unlicensed too — a one-time $99 license removes the production watermark when you ship.

MIT-licensed — no signup, no credit card. Pay once, only when you ship.