driver.js
A dependency-free, ~5kb TypeScript library for building product tours, feature highlights, and focus overlays.
Repository Health
Technical Analysis
driver.js is a lightweight, zero-dependency JavaScript/TypeScript library for highlighting elements on a page and guiding user attention through popovers and dimmed overlays. Rather than being a narrow “tour library,” it exposes a low-level highlight-and-popover primitive that product tours, contextual help, focus shifters, spotlight effects, and simple modals are all built from.
The library ships as ESM and CJS builds with full TypeScript types, weighs roughly 5kb gzipped, and works across all major browsers without any external runtime dependency. It exposes an imperative driver() factory that returns a controller object (drive, moveNext, movePrevious, moveTo, highlight, destroy, and state getters), plus a rich set of lifecycle hooks (onHighlightStarted, onHighlighted, onDeselected, onDestroyStarted, onDestroyed) for manipulating the DOM as steps change.
Because the entire highlight/overlay/popover pipeline is exposed as public building blocks rather than baked into a single “start tour” call, teams building onboarding flows, admin-panel walkthroughs, or contextual help widgets can compose their own UX on top of it instead of fighting a more opinionated tour library.
What You Get
- A
driver()factory returning an imperative controller (drive,moveNext,movePrevious,moveTo,highlight,refresh,destroy) plus state getters (getActiveStep,getActiveElement,isFirstStep,isLastStep) - Per-step and global lifecycle hooks (
onHighlightStarted,onHighlighted,onDeselected,onDestroyStarted,onDestroyed) for intercepting and customizing transitions - A configurable popover system (title, description, custom buttons, progress text, side/alignment placement) rendered next to the highlighted element
- Built-in keyboard navigation (arrow keys, Escape) and
advanceOnClick/overlayClickBehaviorcontrols for click-driven step advancement waitForElementsupport that uses aMutationObserverto hold a step until a dynamically-rendered element appears, rather than polling- A separate
driver.js/hintsentry point for lighter-weight, non-sequential attention hints
Common Use Cases
- Guided product tours that walk new users through an app’s core screens step by step
- One-off feature announcement overlays that highlight a single new UI element
- Contextual help popovers with a dimmed background while a user fills out a form
- Focus-shifting spotlights that draw attention to a specific control before an action is required
- Simple modal-like highlights (a single dummy-element highlight with a popover) without building a full tour
Under The Hood
Architecture
driver.ts composes a small set of single-responsibility modules through one shared Context object created by createContext() (context.ts): events.ts owns global DOM listeners (clicks, arrow keys, Escape) and dispatches them through an emitter on the context, overlay.ts and stage.ts render and transition the dimming layer around the tracked element, popover.ts owns the popover DOM and its buttons/progress text, and highlight.ts orchestrates a single step by resolving the target element (or mounting a synthetic #driver-dummy-element when no element matches, so unmatched steps still render a modal-like popover) and calling into overlay/popover in sequence. The public driver() factory in driver.ts is the only place that owns step-sequencing logic (drive, moveNext, movePrevious, moveTo), delegates rendering to highlight(), and re-resolves steps that declare waitForElement via a MutationObserver rather than a polling loop — a design that keeps a change to the core Context shape from touching more than a handful of files, since every module reads and writes state exclusively through ctx.getState/ctx.setState.
Tech Stack
The package is pure TypeScript with zero runtime dependencies, built with tsdown (plus a postbuild.mjs script) into dual ESM/CJS bundles with generated .d.mts/.d.cts type declarations, verified for consumer correctness with publint and @arethetypeswrong/cli (attw) before publish. It lives inside a pnpm/Turborepo monorepo alongside an Astro-based documentation site (apps/docs) and a playground app that imports the library straight from src/ for hot-reloading example pages. Releases are cut with release-it plus a keep-a-changelog plugin, and CSS is authored as plain stylesheets (driver.css, popover.css, hints.css) shipped alongside the JS bundles rather than through a CSS-in-JS layer.
Code Quality
The packages/driver package has an extensive Vitest suite (over twenty spec files covering navigation, keyboard interaction, scrolling, overlay transitions, event wiring, positioning, hints, hooks, click/advance-on-click behavior, and backward compatibility) run in a jsdom environment with @vitest/coverage-v8 for coverage reporting. tsconfig.json enables strict, noUnusedLocals, noUnusedParameters, and noImplicitReturns, and a GitHub Actions workflow (.github/workflows/ci.yml) runs the pipeline on push. Naming is consistent and small-surfaced (verb-based public methods, __-prefixed internal-only state keys), and modules generally favor early-return guard clauses over nested conditionals.
What Makes It Unique
Rather than exposing a single opinionated “start this tour” call, driver.js splits its own tour behavior into public primitives — highlight() for a single element, drive() for a sequenced walkthrough, and a separate hints entry point for lightweight non-sequential call-outs — so consumers can build custom onboarding UX (spotlights, modals, contextual help) on the same low-level API the library’s own tour behavior is built from, without forking or wrapping a larger framework.
Used by 8 apps in this directory
DocuSeal
Digital Signiture
Open source document signing platform with WYSIWYG PDF builder, multi-party workflows, REST API, and full self-hosting via Docker.
Markdrop
Note Taking
Visual drag-and-drop markdown editor with GitHub-specific blocks, cloud sync, and offline PWA support
Obot
AI Agents
An open-source MCP platform for organizations — host MCP servers, run MCP registries, monitor usage, and build agents and chatbots on top of the Model Context Protocol from one self-hosted deployment.
Screenity
Productivity
Free, privacy-first Chrome screen recorder with real-time annotation, AI camera blur, and a built-in video editor — no sign-in or limits required.
Skyvern
AI Agents · Automation
Skyvern (YC S2023) automates browser-based workflows by pairing LLMs with computer vision, letting agents click, fill, and extract data on sites they've never seen, without brittle XPath selectors that break on every layout change.
ToolJet
Low Code Platforms · No Code Platforms · AI Agents
Open-source AI-native platform to build and deploy internal tools, workflows, and AI agents with a visual drag-and-drop builder and 80+ data source integrations.
Windmill
Automation · Developer Tools
Turn scripts into webhooks, workflows, and auto-generated UIs — the fastest self-hostable workflow engine, 13x faster than Airflow.
Yaffa
Invoicing Finance
Self-hosted personal finance app for long-term financial planning with AI-powered transaction parsing and investment tracking.