Guided product tours, onboarding walkthroughs and feature spotlights - one engine, five frameworks.
A guided-tour library for React, Vue, Solid, Angular and vanilla JavaScript.
Accessible by default, SSR-verified, zero runtime dependencies, ESM-only, written in TypeScript.
Website · Documentation · Live examples · Issues
Most tour libraries are a single DOM script with framework wrappers bolted on, or a framework component you cannot reuse anywhere else. GlowTour.js splits the two: a framework-agnostic engine that owns workflow state, positioning and DOM behavior, and native adapters - real React components, real Vue components, real Angular standalone components - that render it.
| Five native adapters | React, Vue 3, Solid, Angular 18, and native custom elements - not one wrapper reskinned five times. |
| Accessible by default | role="dialog", aria-live step description, focus trap, focus restoration, Escape and arrow-key shortcuts, everywhere. |
| SSR-verified | renderToString + hydration coverage, plus real Next.js, Nuxt, SolidStart and Angular apps tested with Playwright. |
| Zero runtime dependencies | The core ships no dependencies and touches no browser global you did not hand it, which is what keeps SSR safe. |
| Themeable from CSS alone | Every color, radius, spacing, size and transition is a --glow-tour-* token; the popover inherits your font. |
| Analytics-ready | One onEvent callback reports every start, step and exit - with the step id, its duration, and how the user left. |
| Steps that wait | .do(), .wait(), .waitUntil(), .waitUntilElement() and .onTargetEvent() sequence real work between steps. |
Looking for an alternative to Driver.js, Intro.js, Shepherd.js or React Joyride that keeps first-class TypeScript types, server rendering and accessibility across more than one framework? That is the gap this fills.
# pick the adapter for your framework, plus the default theme
npm i @glowhop/react-tour @glowhop/styles-tourOther frameworks
npm i @glowhop/vue-tour @glowhop/styles-tour # Vue 3
npm i @glowhop/solid-tour @glowhop/styles-tour # Solid
npm i @glowhop/angular-tour @glowhop/styles-tour # Angular 18
npm i @glowhop/vanilla-tour @glowhop/styles-tour # custom elementsThe adapters depend on @glowhop/core-tour; you only install it directly to build your own adapter.
import "@glowhop/styles-tour/default.css";
import { createGlowTour, DefaultTour } from "@glowhop/react-tour";
const tour = createGlowTour();
const workflow = tour
.create("welcome")
.step({ id: "name", target: "#workspace-name", title: "Name it", content: "Anything you like." })
.step({ id: "save", target: "#save", title: "Save", content: "That's the whole tour." })
.build();
export function App() {
return (
<>
<input id="workspace-name" />
<button id="save">Save</button>
<button type="button" onClick={() => void tour.run(workflow)}>Start tour</button>
<DefaultTour tour={tour} />
</>
);
}Import the stylesheet once. Nothing renders until an adapter connects a root and a popover - the core owns workflow state, navigation and DOM behavior, but no presentation.
The same workflow in Vue, Solid, Angular and vanilla JS.
The default theme declares every token at zero specificity, so a plain class on any ancestor of the tour re-skins it - no component has to be re-composed:
.terminal-tour {
font-family: ui-monospace, Menlo, monospace; /* the popover is `font: inherit` */
--glow-tour-color-accent: #35f0a0;
--glow-tour-color-surface: #071a12;
--glow-tour-color-text: #d6ffe9;
--glow-tour-radius: 2px;
--glow-tour-popover-width: 320px;
}Light and dark ship together; data-glow-tour-theme="dark" on a wrapper pins one. See the Custom theme example.
popover.placementTryOrder walks top / bottom / left / right until one fits, then falls back to centering - the same collision logic drives the pointer.
| Package | What it is |
|---|---|
@glowhop/react-tour |
React 18 / 19 adapter |
@glowhop/vue-tour |
Vue 3 adapter |
@glowhop/solid-tour |
Solid adapter |
@glowhop/angular-tour |
Angular 18 adapter |
@glowhop/vanilla-tour |
Native custom elements, no framework |
@glowhop/styles-tour |
Default theme, light and dark |
@glowhop/core-tour |
Workflow controller and DOM driver; never used standalone |
Writing an adapter for another framework? @glowhop/core-tour/adapter is the entry point.
- Getting started
- Examples gallery - every demo runs live, with its source
- Accessibility
- Framework versions and verified SSR facts
- JSON configuration
bun install --frozen-lockfile
bun run check && bun run typecheck && bun test && bun run build && bun run packbun run docs serves the website, bun run playground the scratch app. Changesets versions the public packages together; a published GitHub Release triggers the OIDC npm workflow (release notes).
Issues and pull requests are welcome - bug reports are most useful with the framework, adapter version, and a minimal reproduction.
MIT © Glowhop


