@doitrix/product-journey
| Install | |
|---|---|
npm install @doitrix/product-journey |
|
| Latest Version: | 1.5.0 |
| Vue: | 3 |
| License: | MIT |
| Last Updated: | Oct 8, 2026 |
| Links: | npm |
Doitrix Product Journey
A production-grade guided product journey engine for Vue 3.
Most tour libraries are a stack of tooltips. This is a guidance engine: a headless core that owns state, targeting, placement and accessibility, with a default UI layer you can replace entirely.
Status: stable. Verified in a real browser: keyboard navigation, focus restore, the responsive matrix, and an axe-core scan of WCAG 2.0/2.1/2.2 A + AA with 0 violations. The public API is frozen — breaking changes require a major.
Documentation: the journey section of the docs site in DOITRIX-TECH-LABS/ui_packages.
Why
Onboarding should answer one question: "What do I need to know to succeed with this product?" Not "what does every button do?"
The guiding principle throughout: guide the user toward value, not through the interface. The library should disappear into the product.
Design decisions
| Decision | Reason |
|---|---|
| Headless core + default UI | The engine has no Vue and no DOM at import time, so it's testable and replaceable. |
| No Tailwind dependency | A package that forces Tailwind on consumers isn't cleanly reusable. Theming is CSS custom properties. |
| GSAP is an optional peer | Used when installed; a built-in rAF fallback reproduces the same easing curves otherwise. |
| Backdrop blur, not a dark mask | The surrounding UI stays legible. The app should never look broken. |
| Slow, intentional motion | Spotlight 720ms, tooltip 440ms, micro 220ms. Motion communicates, it doesn't decorate. |
bun test only |
Matches the project toolchain. The API is Vitest-compatible if that changes. |
Architecture
Product Journey
│
┌──────────────┴──────────────┐
│ │
Headless Core Default UI
│ │
state · targeting spotlight · tooltip
placement · a11y progress · welcome
│
Adapters
│
motion · storage · analytics
The UI depends on the core. The core never depends on the UI.
Install
bun add @doitrix/product-journey
GSAP is optional — install it only if you want it driving the motion:
bun add gsap
Quick start
const journey = useProductJourney({
id: 'dashboard',
steps: [
{
id: 'create',
target: '[data-tour="create"]',
title: 'Create your first project',
description: 'Start your next project here.',
placement: 'bottom',
},
],
})
journey.start()
Mark targets with a stable attribute, never a structural selector:
<button data-tour="create">New project</button>
Core modules
These are implemented and covered by tests. They are pure and independently usable, including outside Vue.
| Module | Responsibility |
|---|---|
core/machine |
Pure state transitions — the whole navigation contract |
core/placement |
Space measurement, placement flipping, viewport clamping |
core/target |
Null-safe resolution, late-render polling, visibility |
core/persistence |
Pluggable completion storage, corruption-tolerant |
core/motion |
Motion tokens, reduced-motion handling, GSAP adapter |
Reliability guarantees
The engine is built so the host application cannot be broken by the journey:
- A missing target resolves to
null— it never throws - An invalid CSS selector is swallowed, not propagated
- A target that hasn't rendered yet is polled, then skipped on timeout
- Corrupted persisted state is ignored rather than trusted
- An empty journey completes instead of hanging
- Reduced motion collapses every duration to zero and still reaches final state
Theming
Styling is driven by CSS custom properties, so the journey inherits your design system rather than imposing one:
The journey takes every value from @doitrix/tokens, so it matches the rest of
the system and follows light and dark automatically. Any --journey-* property
still overrides the token behind it:
:root {
--journey-primary: #0f766e;
--journey-radius: 4px;
--journey-overlay-blur: 0px;
}
The full list, with the token each one falls back to, is in the theming guide.
Accessibility
Designed in from the start, not bolted on. Target is WCAG 2.2 AA.
| Key | Action |
|---|---|
Tab |
Move between controls |
Enter |
Activate |
Escape |
Exit the journey |
← |
Previous step |
→ |
Next step |
Focus moves into the tooltip on open and returns to the launching element on close. Reduced motion is honoured automatically.
Testing
bun test
The suite covers state, placement, targeting, persistence and motion. bun run build runs the suite before building — a failing test fails
the build.
Versioning
Semantic Versioning. Released together with the other
@doitrix/* packages, at one shared version; see
RELEASING.md.
Roadmap
Shipped and tested
- Headless core — state machine, placement, targeting, persistence, motion
- Engine — events, validation, i18n with RTL, opt-in debug logging
-
useProductJourney()with a keyed multi-journey registry - Component layer — overlay, spotlight, tooltip, progress, welcome, complete
- Keyboard navigation, focus trap and restore, ARIA dialog semantics
- Responsive bottom sheet, resize and scroll recalculation
- Conditional steps and step lifecycle hooks
- Resume where the user left off
- Multi-page journeys across routes
- Slots for custom tooltip, overlay and spotlight
Verified in a real browser
- Nuxt module for auto-import and SSR-safe registration
- axe-core scan, WCAG 2.0/2.1/2.2 A + AA — 0 violations
- End-to-end journey: launch, arrows, skip, finish, Escape, focus restore
- Responsive matrix 1440 → 375, bottom sheet below 640
- Touch targets 44x44 minimum
- Bundle budget enforced by test — core 5.9 KB gzip against a 15 KB budget
Browser support
The last two versions of Chrome, Edge, Firefox and Safari, and iOS Safari 16.4+. Support is only claimed where it's tested.
License
MIT
Related Packages
Vue 3 product tour and onboarding tour components for GlowTour.js. Accessible, S...
Headless Vue 3 binding for the Tour Kit engine — product tours with no React ins...
A comprehensive Vue 3 tour guide library with TypeScript support for Vue and Nux...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.5.0 | ^3.3.0 | MIT | |
| 1.4.1 | ^3.3.0 | MIT | |
| 1.4.0 | ^3.3.0 | MIT | |
| 1.3.0 | ^3.3.0 | MIT | |
| 1.2.0 | ^3.3.0 | MIT | |
| 1.1.0 | ^3.3.0 | MIT | |
| 1.0.1 | ^3.3.0 | MIT | |
| 1.0.0 | ^3.3.0 | MIT |