
Driver.js is a dependency-free JavaScript library for interactive product tours and element spotlights in web apps.
It walks your visitors through configurable steps with popovers, navigation controls, and CSS themes.
Features:
- Animated product tours with configurable steps and popovers.
- Spotlight highlighting for individual page elements.
- Keyboard navigation, step counters, and customizable buttons.
- Click-to-advance actions for interactive walkthroughs.
- Waiting and skipping options for dynamically rendered elements.
- Clickable feature hints with dismissible popovers.
- Onboarding checklists with task progress and lifecycle events.
- Popover themes, overlay styling, and custom callbacks.
How to Use Driver.js:
1. Install Driver.js
Install the driver.js package with package managers.
npm install driver.js # Or: pnpm install driver.js # Or: yarn add driver.js
For projects that use a bundler, import the JavaScript factory and its stylesheet:
import { driver } from "driver.js";
import "driver.js/dist/driver.css";For a plain HTML page, load driver.css and the driver.js.iife.js browser build from a CDN:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/driver.js@latest/dist/driver.css"> <script src="https://cdn.jsdelivr.net/npm/driver.js@latest/dist/driver.js.iife.js"></script>
When using the browser build, obtain driver from the global object. The JavaScript examples below work with either installation method.
const driver = window.driver.js.driver;
2. Highlight a Single Element
Create an element to highlight, then call highlight() from your JavaScript. For a minimal example, put this button on the page:
<button id="save-button" type="button">Save</button>
Initialize Driver.js after the button exists in the DOM.
const driverObj = driver();
driverObj.highlight({
element: "#save-button",
popover: {
title: "Save your work",
description: "Click here to save your changes."
}
});3. Create a Step-by-Step Product Tour
The following example uses three existing elements on a page: #dashboard, #reports, and #settings. Use drive() to start the tour.
const tour = driver({
showProgress: true,
steps: [
{
element: "#dashboard",
popover: { title: "Dashboard", description: "View your overview." }
},
{
element: "#reports",
popover: { title: "Reports", description: "Open your reports." }
},
{
element: "#settings",
popover: { title: "Settings", description: "Update your preferences." }
}
]
});
tour.drive();4. Advance When a Highlighted Element Is Clicked
Set advanceOnClick to true to advance after a click on the highlighted control. This example creates the second step’s button only when the first button is clicked. waitForElement handles delayed rendering. Click-to-advance requires interaction with the element to be enabled.
<button id="open-menu" type="button">Open menu</button>
After the browser loads the button, run the following JavaScript:
document.querySelector("#open-menu").addEventListener("click", () => {
if (!document.querySelector("#menu-item")) {
const button = document.createElement("button");
button.id = "menu-item";
button.textContent = "Settings";
document.body.append(button);
}
});
const tour = driver({
showProgress: true,
steps: [
{
element: "#open-menu",
advanceOnClick: true,
popover: { title: "Open the menu", description: "Click the highlighted button." }
},
{
element: "#menu-item",
waitForElement: 3000,
skipMissingElement: true,
popover: { title: "Choose an item", description: "Select an option from the menu." }
}
]
});
tour.drive();5. Customize a Tour with CSS
Set popoverClass on the driver or an individual popover. Apply the CSS override after the Driver.js stylesheet.
const tour = driver({
popoverClass: "product-tour",
stagePadding: 8,
overlayOpacity: 0.6
});
tour.highlight({
element: "#save-button",
popover: { title: "Save", description: "Save your progress." }
});.driver-popover.product-tour {
background: #172554;
color: #fff;
}
.driver-popover.product-tour .driver-popover-title,
.driver-popover.product-tour .driver-popover-description {
color: #fff;
}
:root {
--driver-popover-font-family: Arial, sans-serif;
}6. Create Contextual Feature Hints
Hints use driver.js/hints and hints.css. Beacons can open in any order, and dismissed hints can be restored programmatically. The example uses two existing buttons with IDs export-button and filter-button.
<button id="export-button" type="button">Export</button> <button id="filter-button" type="button">Filter</button>
import { hints } from "driver.js/hints";
import "driver.js/dist/hints.css";
const productHints = hints({
hints: [
{
id: "export",
element: "#export-button",
popover: {
title: "Export data",
description: "Download your report here."
}
},
{
id: "filter",
element: "#filter-button",
beacon: { side: "right", align: "center" },
popover: {
title: "Filter results",
description: "Choose which results to display."
}
}
]
});
productHints.show();For the browser build, load hints.iife.js and hints.css. The factory is available as window.driverHints.hints. The hints stylesheet is self-contained.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/driver.js@latest/dist/hints.css"> <script src="https://cdn.jsdelivr.net/npm/driver.js@latest/dist/hints.iife.js"></script>
7. Create an Onboarding Checklist
Checklists use driver.js/checklist. Load driver.css and checklist.css for checklists that launch tours. The example uses a dashboard element and a help link, which you should replace with pages in your application. A checklist item can launch a tour, open a link, or run an action. Use stable item IDs when restoring saved progress.
<section id="dashboard">Dashboard overview</section>
import { checklist } from "driver.js/checklist";
import "driver.js/dist/driver.css";
import "driver.js/dist/checklist.css";
const onboarding = checklist({
id: "getting-started",
title: "Get started",
items: [
{
id: "tour",
title: "Take the dashboard tour",
tour: [
{
element: "#dashboard",
popover: { title: "Dashboard", description: "Your overview." }
}
]
},
{
id: "help",
title: "Read the help page",
href: "/help"
}
]
});
onboarding.show();In a plain HTML project, load the checklist browser build after the main Driver.js script. Its factory is window.driverChecklist.checklist.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/driver.js@latest/dist/checklist.css"> <script src="https://cdn.jsdelivr.net/npm/driver.js@latest/dist/checklist.iife.js"></script>
8. Record Checklist Progress
Driver.js accepts an initial array of completed task IDs through completed and reports subsequent changes through onProgress. Your application manages persistence. For example, this callback saves the completed IDs in localStorage.
const savedChecklist = checklist({
id: "setup",
items: [
{ id: "profile", title: "Complete your profile", href: "/profile" }
],
completed: JSON.parse(localStorage.getItem("setup-progress") || "[]"),
onProgress: ({ completed }) => {
localStorage.setItem("setup-progress", JSON.stringify(completed));
}
});
savedChecklist.show();9. Control Tour Navigation with Callbacks
Custom onNextClick and onDoneClick callbacks take control of the corresponding button actions. Call moveNext() and destroy() yourself when you want those actions to proceed. This example uses centered steps and requires no page selectors.
const manualTour = driver({
steps: [
{ popover: { title: "Welcome", description: "First step." } },
{ popover: { title: "Finished", description: "Last step." } }
],
onNextClick: () => manualTour.moveNext(),
onDoneClick: () => manualTour.destroy()
});
manualTour.drive();Driver.js Configuration Options:
Pass these options to driver({...}), or update an instance with setConfig({...}).
Tour Appearance and Navigation
| Option | Description |
|---|---|
steps | Array of DriveStep objects for a tour. |
animate | Enables animated transitions. Default: true. |
duration | Transition and fade duration in milliseconds when animations are enabled. Default: 400. |
overlayColor | Overlay color. Default: black. |
overlayOpacity | Overlay opacity. Default: 0.5. |
overlayClickBehavior | "close", "nextStep", "none", or a callback. Default: "close". |
allowClose | Controls closing the popover through the backdrop. Default: true. |
allowScroll | Allows page scrolling during the tour. Set false to lock body scroll. Default: true. |
smoothScroll | Enables smooth scrolling to the current element. Default: false. |
stagePadding | Padding around the spotlight cutout, in pixels. Default: 10. |
stageRadius | Corner radius of the spotlight cutout, in pixels. Default: 5. |
allowKeyboardControl | Enables keyboard navigation. Default: true. |
disableActiveInteraction | Blocks interaction with the highlighted element. Default: false. |
advanceOn | What completes a step, as if the next button was pressed: a DOM event name or list of names fired on the highlighted element (“contextmenu”, [“dblclick”, “contextmenu”]), or { event, when } where the step only completes when when() returns true. Default: null. |
advanceOnClick | Advances when the highlighted element receives a click. Default: false. |
onInteraction | Called for every click, auxclick, contextmenu and dblclick during a step, before your app’s handlers. |
allowedElements | keeps menus and popups opened by a step usable above the overlay. Default: null. |
onElementMissing | Recover when a step’s element disappears or a wait times out. Default: null. |
skipMissingElement | Skips a step if its element cannot be found. Default: false. |
waitForElement | Wait time for a missing step element in milliseconds. Default: 0. |
popoverClass | Custom CSS class for tour popovers. |
popoverOffset | Distance from the highlighted element to the popover, in pixels. Default: 10. |
showButtons | Visible buttons from next, previous, and close. Tours show all three by default. Single highlights show none. |
disableButtons | Buttons to disable from next, previous, and close. |
showProgress | Displays progress text. Default: false. |
progressText | Progress template using {{current}} and {{total}}. |
nextBtnText | Text for the Next button. |
prevBtnText | Text for the Previous button. |
doneBtnText | Text for the final Done button. |
closeBtnLabel | Accessible label for the close button. Default: "Close". |
Tour Callbacks and Lifecycle Hooks
Lifecycle callbacks receive the current element, step object, and an options object with config, state, driver, and index. Destroy callbacks also receive reason, and onDeselected receives it when a tour closes.
| Option | Description |
|---|---|
onPopoverRender | Runs after the popover DOM is rendered. Receives PopoverDOM and an options object. |
onHighlightStarted | Runs before a step begins highlighting. |
onHighlighted | Runs after a step is highlighted. |
onDeselected | Runs when the current step is deselected. |
onDestroyStarted | Runs before teardown. If defined, call destroy() after any custom exit confirmation. |
onDestroyed | Runs after the tour or highlight is destroyed. |
onNextClick | Overrides the default Next action. |
onPrevClick | Overrides the default Previous action. |
onCloseClick | Overrides the default close-button action. |
onDoneClick | Replaces the last step’s Done action and takes precedence over onNextClick. Call destroy() to close the tour. |
Step Configuration
Each step accepts a selector, an element, or a function that returns a DOM element. Omit element for an intentional popover centered on the screen.
| Option | Description |
|---|---|
element | CSS selector, DOM element, or function returning an element. |
popover | Step-specific popover configuration. |
disableActiveInteraction | Overrides interaction blocking for this step. |
advanceOn | Step-level versions of the driver options with the same name. Each overrides the driver-level value for this step. Default: false. |
allowedElements | keeps menus and popups opened by a step usable above the overlay. Default: null. |
onElementMissing | Recover when a step’s element disappears or a wait times out. Default: null. |
advanceOnClick | Overrides click-to-advance for this step. |
onInteraction | Called for every click, auxclick, contextmenu and dblclick during a step, before your app’s handlers. |
skipMissingElement | Overrides missing-element skipping for this step. |
waitForElement | Overrides the wait time in milliseconds for this step. |
data | Arbitrary step data available in lifecycle callbacks. |
onDeselected | Step-level deselection callback. |
onHighlightStarted | Step-level callback before highlighting. |
onHighlighted | Step-level callback after highlighting. |
Popover Configuration
Popover options can be defined for individual steps. The popover can switch sides when its preferred placement does not fit in the viewport. title and description accept HTML, so escape any untrusted content before displaying it.
| Option | Description |
|---|---|
title | Popover title. Accepts an HTML string. |
description | Popover description. Accepts an HTML string. |
side | "top", "right", "bottom", or "left". Default: "bottom". |
align | "start", "center", or "end". Default: "start". |
showButtons | Popover buttons to display. |
disableButtons | Popover buttons to disable. |
nextBtnText | Custom Next label. |
prevBtnText | Custom Previous label. |
doneBtnText | Custom Done label. |
closeBtnLabel | Accessible close-button label. Default: "Close". |
showProgress | Displays step progress. |
progressText | Progress template with {{current}} and {{total}}. |
popoverClass | Custom class applied to the popover. |
onPopoverRender | Callback after the popover DOM is rendered. |
onNextClick | Overrides Next. Call moveNext() to advance. |
onPrevClick | Overrides Previous. Call movePrevious() to go back. |
onCloseClick | Overrides the close button. Call destroy() to close. |
onDoneClick | Overrides Done on the last step. Tour closure becomes your responsibility. |
Driver.js Methods:
| Method | Description |
|---|---|
drive(index?) | Starts a tour. The optional zero-based index selects its starting step. |
moveNext() | Moves to the next step. |
movePrevious() | Moves to the previous step. |
moveTo(index) | Moves to a step by zero-based index. |
hasNextStep() | Checks for a next step. |
hasPreviousStep() | Checks for a previous step. |
isFirstStep() | Checks whether the current step is the first. |
isLastStep() | Checks whether the current step is the last. |
getActiveIndex() | Returns the active step index. |
getActiveStep() | Returns the active step configuration. |
getPreviousStep() | Returns the previous step configuration. |
getNextStep() | Returns the next step configuration. |
getActiveElement() | Returns the active DOM element. |
getPreviousElement() | Returns the previous DOM element. |
isActive() | Checks whether a tour or highlight is active. |
refresh() | Recalculates and redraws the highlight. |
getConfig() | Returns the current driver configuration. |
setConfig(config) | Updates the configuration. |
setSteps(steps) | Replaces the configured tour steps. |
getState() | Returns the current driver state. |
highlight(step) | Highlights the element described by one step object. |
updatePopover(options) | Change the visible popover in place. |
nudge(options) | Draw attention to the popover with a short shake. |
destroy() | Closes the tour or highlight and invokes destruction hooks. |
State and Popover DOM Objects
The object returned by getState() and passed to hooks can contain the following state properties. Popover callbacks receive the exposed DOM references listed separately.
| Property | Description |
|---|---|
isInitialized | Whether the driver has initialized. |
activeIndex | Active tour step index. |
activeElement | DOM element for the active step. |
activeStep | Configuration of the active step. |
previousElement | Previously highlighted DOM element. |
previousStep | Previously active step configuration. |
popover | Popover DOM object. |
PopoverDOM Properties
| Property | Description |
|---|---|
wrapper | Popover wrapper element. |
arrow | Popover arrow element. |
title | Title element. |
description | Description element. |
footer | Footer element. |
progress | Progress element. |
previousButton | Previous button element. |
nextButton | Next button element. |
closeButton | Close button element. |
footerButtons | Footer button container element. |
Destroy Reasons
Destroy hooks receive options.reason: "done" for completed navigation, "close" for the close button, "escape" for Escape, "overlay" for backdrop clicks, "replaced" when another driver instance becomes active, and "api" for direct API termination. onDeselected receives this reason only when the tour ends. A normal transition between steps has no destroy reason.
Feature Hints Configuration and API:
Hints Instance Options
| Option | Description |
|---|---|
hints | Array of hint objects. |
beacon | Default beacon configuration for every hint. |
buttonText | Dismiss-button text. Default: "Got it". |
popoverClass | Custom CSS class for hint popovers. |
popoverOffset | Distance between the popover and its anchor. Default: 10. |
overlay | Dims the rest of the page when a hint opens. Default: false. |
overlayColor | Overlay color. Default: "#000". |
overlayOpacity | Overlay opacity. Default: 0.7. |
onOpen | Callback when a hint opens. |
onDismiss | Callback when a hint is dismissed. |
onButtonClick | Custom button action. Overrides automatic dismissal. |
Hint Options
An individual hint takes precedence over the instance defaults. The beacon object controls placement and pulse behavior. popover configures the help message shown when the beacon is clicked.
| Option | Description |
|---|---|
element | Required selector, element, or element-returning function. |
id | Stable hint identifier, defaulting to its array index. |
beacon | Individual beacon settings. |
popover | Individual hint popover settings. |
onOpen | Hint-level open callback. |
onDismiss | Hint-level dismiss callback. |
data | Custom metadata carried by the hint. |
Beacon Options
| Option | Description |
|---|---|
beacon.side | top, right, bottom, or left. Default: top. |
beacon.align | start, center, or end. Default: end. |
beacon.offsetX | Horizontal offset in pixels. Default: 0. |
beacon.offsetY | Vertical offset in pixels. Default: 0. |
beacon.animate | Controls the pulse animation. Default: true. |
beacon.className | Custom class for the beacon. |
Hint Popover Options
| Option | Description |
|---|---|
popover.title | Help popup title. |
popover.description | Help popup description. |
popover.side | top, right, bottom, or left. |
popover.align | start, center, or end. |
popover.popoverClass | Custom class for this popup. |
popover.showButton | Shows a dismiss button. Default: true. |
popover.buttonText | Overrides the hint instance button text. |
popover.onButtonClick | Custom button handler for this hint. |
popover.onPopoverRender | Receives the rendered PopoverDOM and { hint, hints }. |
Hints Methods
| Method | Description |
|---|---|
show() | Displays beacons and picks up newly available elements. |
hide() | Removes beacons and their listeners. |
open(id) | Opens a hint popover by identifier or index. |
close() | Closes the current popover and keeps its beacon. |
dismiss(id) | Dismisses a hint and fires onDismiss. |
restore(id) | Restores one dismissed hint. |
restoreAll() | Restores every dismissed hint. |
setHints(hints) | Replaces configured hints and resets dismissals. |
getHints() | Returns the configured hint definitions. |
getActive() | Returns the currently open hint, if any. |
isVisible() | Checks if beacons are visible. |
refresh() | Repositions beacons, open popover, and overlay. |
Onboarding Checklist Configuration and API:
Checklist Options
| Option | Description |
|---|---|
id | Required checklist identifier, included in events. |
items | Required array of checklist item objects. |
title | Panel title. Default: "Get started". |
description | Text below the title. |
launcherText | Launcher button text. Defaults to the checklist title. |
completeTitle | Title displayed after all items are completed. |
completeDescription | Description displayed after all items are completed. |
completeLauncherText | Launcher text displayed after completion. |
progressText | Template using {{done}}, {{total}}, {{remaining}}, and {{percent}}. Default: "{{done}} of {{total}}". |
launcherProgressText | Launcher count template with the progress placeholders {{done}}, {{total}}, {{remaining}}, and {{percent}}. Empty text hides the count. Default: "{{done}}/{{total}}". |
launcher | Displays the floating launcher. Default: true. |
position | "bottom-right", "bottom-left", "top-right", or "top-left". Default: "bottom-right". |
offset | Screen-edge offset object with optional x and y. Default: 20 pixels, or 12 pixels on screens narrower than 480 pixels. |
className | Custom checklist widget CSS class. |
allowManualComplete | Allows the visitor to check and uncheck tasks directly. Default: false. |
completed | Array of IDs already marked complete. |
onProgress | Runs after progress changes with { completed, done, total }. Saved IDs can include items no longer in the list. |
onItemComplete | Runs when an item is completed. |
onComplete | Runs when all items have been completed. |
onEvent | Receives checklist events including the checklist ID, type, timestamp, and optional item ID or reason. |
Checklist Item Options
Set id and title for each checklist item. A tour completes its item when the tour finishes, and completeWhen overrides automatic completion logic.
| Option | Description |
|---|---|
id | Required stable task identifier. |
title | Required task title. HTML is accepted. |
description | Optional task description. |
tour | Tour steps, a Driver.js configuration, or a Driver.js instance. |
href | URL followed when the task is activated. |
action | Function executed when the task is activated. |
completeWhen | Function returning a boolean completion state. |
allowManualComplete | Overrides manual completion for the item. |
data | Custom item metadata available to callbacks. |
Checklist Methods
| Method | Description |
|---|---|
show() | Mounts the checklist widget and launcher when enabled. |
hide() | Removes the checklist widget. |
open() | Opens the checklist panel. |
close() | Closes the panel and keeps the launcher. |
toggle() | Opens or closes the panel. |
start(id) | Runs the matching checklist item. |
complete(id) | Marks an item complete. |
uncomplete(id) | Marks an item incomplete. |
reset() | Marks all items incomplete. |
refresh() | Rechecks item completion functions. |
getProgress() | Returns completed IDs and done / total counts. |
getItems() | Returns checklist item definitions. |
isVisible() | Checks if the checklist widget is displayed. |
isOpen() | Checks if its panel is open. |
Checklist Events
The onEvent callback receives kind: "checklist", id, type, and timestamp. Some events also include itemId or a tour-ending reason.
shown: The checklist becomes visible.hidden: The checklist becomes hidden.opened: The panel opens.closed: The panel closes.item_started: A checklist item starts.item_completed: A task is marked complete.item_uncompleted: A task is marked incomplete.tour_ended: An item tour ends.completed: All tasks have been completed.reset: The checklist is reset.
CSS Classes and Custom Properties:
Driver.js exposes these styling hooks for tour popovers and the highlighted page. Classes for rendered popover placement reflect the actual position after any automatic repositioning.
Tour and Popover CSS Classes
| Option | Description |
|---|---|
.driver-popover | Popover container. |
.driver-popover-arrow | Arrow pointing to the highlighted element. |
.driver-popover-side-top | Popover appears above the element. |
.driver-popover-side-right | Popover appears to the right. |
.driver-popover-side-bottom | Popover appears below the element. |
.driver-popover-side-left | Popover appears to the left. |
.driver-popover-align-start | Popover aligns to the start edge. |
.driver-popover-align-center | Popover is centered on its aligned edge. |
.driver-popover-align-end | Popover aligns to the end edge. |
.driver-popover-title | Popover title. |
.driver-popover-description | Popover description. |
.driver-popover-close-btn | Close button. |
.driver-popover-footer | Footer. |
.driver-popover-progress-text | Tour progress label. |
.driver-popover-prev-btn | Previous button. |
.driver-popover-next-btn | Next button. |
.driver-popover-footer-btn | Default footer button styling hook. |
.driver-popover-done-btn | Modifier applied to the Next button on the last step. |
.driver-active | Applied to the page body during an active highlight or tour. |
.driver-fade | Page class for animated highlights. |
.driver-simple | Page class for nonanimated highlights. |
.driver-overlay | Overlay element. |
.driver-active-element | Highlighted element. |
Popover CSS Custom Properties
| Property | Description |
|---|---|
--driver-popover-font-family | Font for tour popovers, hint popovers, and checklists. Set it on :root or a parent element. |
Hint Styling
The beacon class can be customized through beacon.className. The following CSS properties control size and color.
| Option | Description |
|---|---|
.driver-hint | Class of a feature-hint beacon. |
--driver-hint-size | CSS custom property controlling beacon size. |
--driver-hint-color | CSS custom property controlling beacon color. |
Checklist CSS Custom Properties
Use className for checklist themes, position and offset for placement, and the following public CSS custom properties for styling. Checklist text inherits --driver-popover-font-family.
| Option | Description |
|---|---|
--driver-checklist-color | CSS custom property for accent color, checkmarks, progress, and focus rings. |
--driver-checklist-offset-x | Horizontal distance of the checklist from the viewport edge. |
--driver-checklist-offset-y | Vertical distance of the checklist from the viewport edge. |
Checklist Component CSS Classes
| Option | Description |
|---|---|
.driver-checklist | Checklist wrapper. |
.driver-checklist-complete | Applied once every item is complete. |
.driver-checklist-launcher | Floating launcher. |
.driver-checklist-launcher-text | Launcher label. |
.driver-checklist-launcher-count | Launcher count. |
.driver-checklist-panel | Expanded panel. |
.driver-checklist-header | Panel header. |
.driver-checklist-title | Panel title. |
.driver-checklist-description | Panel description. |
.driver-checklist-close-btn | Panel close button. |
.driver-checklist-progress | Progress section. |
.driver-checklist-progress-bar | Progress bar background. |
.driver-checklist-progress-fill | Progress bar fill. |
.driver-checklist-progress-text | Progress label. |
.driver-checklist-items | Task list. |
.driver-checklist-item | Individual task. |
.driver-checklist-item-done | Completed task. |
.driver-checklist-check | Check-circle control. |
.driver-checklist-item-trigger | Task link or button. |
.driver-checklist-item-title | Task title. |
.driver-checklist-item-description | Task description. |
FAQs:
Q: Why does driverObj.start() fail?
A: Tours now start with driverObj.drive(). Pass the steps to driver({ steps: [...] }) before calling it.
Q: Why does my tour stop advancing after I set onNextClick?
A: A custom click handler replaces the automatic Next action. Call driverObj.moveNext() from the handler after your own logic finishes. The final Done callback must call destroy() to close the tour.
Q: Why does a tour step show a centered popover?
A: A missing element normally triggers a centered popover. Use skipMissingElement to bypass missing elements or waitForElement to wait for dynamically inserted elements. A step with no element intentionally uses a centered popover.
Q: What happens when I start another Driver.js tour?
A: Only one tour or highlight instance appears at once. Starting another instance closes the active tour or highlight. Its destroy reason is "replaced". Instances retain their own configuration and steps.
Q: How do I save dismissed hints and completed checklist tasks?
A: Save hint IDs in onDismiss and dismiss them again after recreating the hints instance. For checklists, save the IDs from onProgress and pass them back through completed when initializing the checklist. Persistence belongs to your application.
Alternatives and Related Resources:
- Create Interactive Web App Tours in Under 10KB – GTourJS
- Create Interactive Guided Tours In App – TourGuide.js
- Lightweight Vanilla JS Library for Interactive Guided Tours – Boarding.js
- Lightweight User Tour/Onboarding Library for Web Apps – CodingIntroJS
- Best Free Guided Tour JavaScript Plugins
- 10 Best Tour Plugins To Guide Visitors Through Your App
Changelog:
v1.12.1 (11/12/2026)
- Added more API
- Bugfixes
v1.11.0 (11/09/2026)
- Added more API
- Bugfixes.
v1.10.2 (10/19/2026)
- Bugfixes
v1.10.1 (10/17/2026)
- Adds launcher: false to disable checklists floating launcher
- Fixes hints and popovers inside <dialog> elements.
- Fixes popover clicks when the event target is a text node.
v1.10.0 (10/16/2026)
- Added support for checklists.
- New reason option on the destroy hooks to distinguish between destroy reasons.
v1.9.0 (10/03/2026)
- Added closeBtnLabel (driver and step level) to set the close button’s aria-label, for translated tours. Defaults to Close.
- Added overlayClickBehavior: “none” to ignore overlay clicks while Escape and the close button still close the tour.
- Keyboard control follows the popover buttons: arrow keys do nothing when their button is hidden or disabled, and Escape does nothing when the close
button is disabled. - The current popover is hidden while waitForElement waits for the next step’s element, so a stale step no longer stays on screen.
- Only one instance is on screen at a time. Starting a tour or highlight closes any other active instance. The replaced instance runs onDeselected and onDestroyed, but not onDestroyStarted.
- Bugfixes.
v1.8.0 (07/18/2026)
- Added Hints, which display pulsing beacons with clickable popovers and an optional overlay.
- Added advanceOnClick (driver and step level) to advance the tour by clicking the highlighted element itself.
- Added waitForElement (driver and step level) to wait up to N ms for a step’s element before treating it as missing.
- Changed Popover internals shared between tours and hints.
- Fixed skipMissingElement: the last reachable step now shows Done and runs onDoneClick. Step queries like isLastStep() account for skips.
v1.7.0 (07/14/2026)
- Added skipMissingElement option to skip a step whose target element is missing
- Added index on the options passed to every hook
- Added –driver-popover-font-family CSS variable to set the popover font
- The popover title and description now render in the default font stack. Set –driver-popover-font-family to use your own
- Fixed bugs
v1.6.0 (06/26/2026)
- Updated transition timing controls (the current option is
duration). - Added allowScroll config to lock body scroll while a tour is active.
- Added onDoneClick hook, fired when the done button on the final step is clicked.
- Added data property on a step for passing arbitrary data, accessible from hooks for custom per-step logic.
- Custom popover footer buttons no longer get auto styled, style them using .driver-popover-footer button selector.
- The popover exposes driver-popover-side-* and driver-popover-align-* classes as per the rendered side and alignment.
- Fixed bugs.
v1.5.0 (06/24/2026)
- Add done-btn class to next button
- Pass final state to onDestroyed hook
- Keep tour open on arrow-left at step 1
- Remove button text-shadow ghost text
- Fire onNextClick on overlay nextStep
- Add getNextStep to the driver API
- Remove unicode characters from buttons
v1.4.0 (11/19/2025)
- overlayClickBehavior now supports callbacks
v1.3.6 (05/13/2025)
- Bugfixes
v1.3.4 (02/02/2025)
- Bugfixes
v1.3.1 (11/11/2023)
- Update
v1.3.0 (09/11/2023)
- Update vite configuration to support ES2019
- Popover title to support HTML
- Fixes wrong type definition for onPopoverRender configuration
- Add validation on class name
- Upgrade all the dependencies to latest
v1.2.0 (07/24/2023)
- Adds new disableActiveInteraction config to disable interaction with the active element.
- Bugfixes
v1.1.0 (07/24/2023)
- Implemented focus trapping
- Adds ARIA attributes and use of semantic markup.
v1.0.3 (07/07/2023)
- Rewritten in TypeScript.
- Popover is much more intelligent in its placement
- Supports async steps to allow more dynamic and interactive guides
- Support for non-element steps (i.e. where you just want to show a popup on screen)
- Ask for confirmation before exit
- Support for scrollable elements
- Allows showing progress during product tours
- More customizable than ever with more hooks
- Improved documentation with code samples for usage
- Popover hooks allow you to have more control over the popover rendering
v0.9.8 (03/21/2020)
- Resolve merge conflicts
v0.9.8 (02/29/2020)
- Adds step counter feature
v0.9.7 (06/15/2019)
- Updates Dependencies
v0.9.6 (06/01/2019)
- Fix touch issue
- Error when hiding on an element without popover
v0.9.3 (02/24/2019)
- Update
v0.9.2 (02/10/2019)
- Add more options
- Doc updated
v0.7.1 (10/12/2018)
- Add more options
- Optimize
v0.6.0 (06/30/2018)
- Add support for asynchronous actions
v0.5.2 (05/23/2018)
- Add keyboardControl option and typo in readme







