Skip to content

Introduction

Accessible product tours built on native browser primitives. No positioning library. No portals. No fighting with z-index, and no hand-rolled focus trap.

MIT licensed. 9.7 kB minified + gzipped, stylesheet included. Zero runtime dependencies.

Terminal window
npm install @cmunns/guidepost
import { Tour } from '@cmunns/guidepost';
const tour = new Tour({
id: 'onboarding',
steps: [
{ title: 'Welcome', text: 'A quick tour.', placement: 'center' },
{ target: '#sidebar', title: 'Navigation', text: 'Everything lives here.', placement: 'right-start' },
{ target: '#search', title: 'Try it', text: 'Type to continue.', focus: 'target',
advanceOn: { event: 'input', when: (e) => e.target.value.length > 2 } },
],
});
tour.start();

Every example in these docs runs live at the live demo.

What it’s built on

Popover API

The card lives in the top layer, so you’re never portaling it somewhere else, escalating z-index, or trying to escape overflow: hidden.

CSS anchor positioning

The browser keeps the card stuck to its target. Browsers that don’t have it yet get a measured JS fallback.

clip-path spotlight

One element, and you get a click-through hole for free, so the user can actually do the thing the step is talking about.

inert

The platform handles the focus trap. Everything else is untabbable, unclickable, and invisible to screen readers. No keydown interception, no sentinel nodes.

Where to go next

Install

Install the package and decide who owns the CSS pipeline.

Quick start

Quick start. A tour is an array of steps and a call to start().

Blocking modes

Blocking modes. Three combinations, and this choice matters way more than any styling decision.