Skip to content

Core API

@walkrstudio/core provides the step builders, composers, and the walkr() factory that together define a walkthrough.

walkr(options)

Creates a Walkthrough object — the top-level unit that the engine and CLI consume.

ts
import { walkr, moveTo, click } from "@walkrstudio/core";

export default walkr({
  url: "https://example.com",
  steps: [moveTo("#btn", { duration: 500 }), click("#btn")],
  title: "Example",
  description: "A short walkthrough.",
  viewport: { width: 1920, height: 1080 },
  cursor: { shape: "circle", color: "#22d3ee", size: 24 },
  zoom: { defaultLevel: 1, easing: "cubic-bezier(0.42, 0, 0.58, 1)" },
});

WalkthroughOptions

FieldTypeDescription
urlstring(required) The target page URL.
stepsStep[](required) Array of steps to execute.
titlestringOptional walkthrough title.
descriptionstringOptional description.
viewportViewportDesign viewport { width, height }.
cursorCursorConfigDefault cursor appearance.
zoomZoomDefaultsDefault zoom level and easing.

CursorConfig

FieldTypeDefaultDescription
shape"circle" | "arrow" | "dot" | "svg" | "cursor-01" | "cursor-02" | "cursor-03"Cursor shape. Use a cursor-* preset for a ready-made pointer.
colorstringCursor colour.
sizenumberCursor size in pixels.
shadowbooleanShow drop shadow.
clickColorstringColour of the click ripple.
svgContentstringRaw SVG string (when shape is "svg").
offset{ x: number; y: number }{ x: 0.5, y: 0.5 }Hotspot offset as a fraction of cursor size.

Cursor Presets

Built-in cursor presets you can use by setting shape to the preset name. The color option controls the cursor colour.

cursor-01
cursor-02
cursor-03
ts
// Example: use cursor-02 preset with a custom colour
walkr({
  url: "https://example.com",
  cursor: { shape: "cursor-02", color: "#10b981", size: 28 },
  steps: [/* ... */],
});

Step Builders

Every step builder returns a Step object with id, type, options, and duration.

moveTo(selector, options?)

Move the virtual cursor to a DOM element.

ts
moveTo("#my-button", { duration: 600, easing: "ease-in-out" });
OptionTypeDefaultDescription
durationnumber0Animation duration in ms.
easingstringCSS easing function.
followbooleanKeep cursor attached to the element.
cursorPartial<CursorConfig>Per-step cursor override.

moveToCoords(x, y, options?)

Move the cursor to absolute coordinates.

ts
moveToCoords(960, 540, { duration: 400 });

Accepts the same options as moveTo.

click(selector, options?)

Click a DOM element.

ts
click("#submit-btn");
click("#item", { button: "right", double: true });
OptionTypeDefaultDescription
button"left" | "right" | "middle""left"Mouse button.
doublebooleanfalseDouble-click.
cursorPartial<CursorConfig>Per-step cursor override.

clickCoords(x, y, options?)

Click at absolute coordinates.

ts
clickCoords(100, 200, { button: "left" });

Accepts the same options as click.

type(text, options?)

Type text character by character.

ts
type("hello@example.com", { selector: "#email", delay: 40 });
OptionTypeDefaultDescription
delaynumber0Delay between keystrokes in ms.
selectorstringTarget input element.
cursorPartial<CursorConfig>Per-step cursor override.

The step duration is computed as text.length * delay.

scroll(x, y, options?)

Scroll the page by (x, y) pixels.

ts
scroll(0, 300, { smooth: true });
OptionTypeDefaultDescription
smoothbooleanUse smooth scrolling.
cursorPartial<CursorConfig>Per-step cursor override.

wait(ms)

Pause playback for the given number of milliseconds.

ts
wait(1000); // wait one second

waitForSelector(selector, options?)

Wait until a DOM element matching selector exists (and optionally is visible).

ts
waitForSelector(".modal", { timeout: 3000, visible: true });
OptionTypeDefaultDescription
timeoutnumber5000Maximum wait time in ms.
visiblebooleanAlso require the element to be visible.
cursorPartial<CursorConfig>Per-step cursor override.

waitForNavigation(options?)

Wait for a page navigation to complete.

ts
waitForNavigation({ waitUntil: "networkidle", timeout: 8000 });
OptionTypeDefaultDescription
timeoutnumber5000Maximum wait time in ms.
waitUntil"load" | "domcontentloaded" | "networkidle""load"When to consider navigation complete.
cursorPartial<CursorConfig>Per-step cursor override.

highlight(selector, options?)

Highlight a DOM element with an optional spotlight overlay.

ts
highlight("#feature-card", {
  spotlight: true,
  color: "#3b82f6",
  duration: 2000,
  backdropOpacity: 0.3,
  padding: 8,
  borderRadius: 6,
});
OptionTypeDefaultDescription
colorstringHighlight border / glow colour.
durationnumber0How long the highlight stays visible (ms).
spotlightbooleanDim the rest of the page behind the element.
backdropOpacitynumberOpacity of the spotlight backdrop (0–1).
borderRadiusnumberBorder radius of the highlight box (px).
paddingnumberExtra padding around the element (px).
cursorPartial<CursorConfig>Per-step cursor override.

tooltip(selector, text, options?)

Show a tooltip anchored to a DOM element.

ts
tooltip("#help-icon", "Click here to get started", {
  position: "bottom",
  duration: 3000,
  title: "Tip",
});
OptionTypeDefaultDescription
durationnumber3000How long the tooltip is shown (ms).
position"top" | "bottom" | "left" | "right""top"Tooltip placement relative to the element.
titlestringBold title line above the text.
cursorPartial<CursorConfig>Per-step cursor override.

narrate(src, options?)

Play an audio file during the walkthrough.

ts
narrate("/audio/intro.mp3", { duration: 5000, volume: 0.8 });
OptionTypeDefaultDescription
durationnumberDuration in ms. If omitted, derived from audio length at runtime.
volumenumber1Volume level from 0 to 1.
loopbooleanfalseWhether to loop the audio.

zoom(level, options?)

Zoom the viewport to a given level.

ts
zoom(2, { x: 500, y: 300, easing: "ease-out" });
OptionTypeDefaultDescription
xnumberZoom origin X coordinate.
ynumberZoom origin Y coordinate.
easingstring"cubic-bezier(0.42, 0, 0.58, 1)"CSS easing function.
followbooleanKeep zoom centred on cursor.
cursorPartial<CursorConfig>Per-step cursor override.

Default animation duration is 360 ms.

pan(x, y, options?)

Pan (translate) the viewport to a position.

ts
pan(200, 100, { duration: 500, easing: "ease-in-out" });
OptionTypeDefaultDescription
durationnumber360Animation duration in ms.
easingstring"cubic-bezier(0.42, 0, 0.58, 1)"CSS easing function.
cursorPartial<CursorConfig>Per-step cursor override.

hover(selector, options?)

Hover over a DOM element. The engine moves the cursor to the element, dispatches mouseover and mouseenter events, holds the hover for the configured duration, then dispatches mouseleave and mouseout to end the hover. The element returns to its default (non-hovered) appearance after cleanup.

ts
hover(".dropdown-trigger", { duration: 1500 });
hover("#tooltip-target");
OptionTypeDefaultDescription
durationnumber0How long to hold the hover state (ms).
cursorPartial<CursorConfig>Per-step cursor override.

Hover-End Cleanup

Unlike a bare moveTo (which leaves the cursor positioned over the element), hover explicitly dispatches leave events when the duration expires. This ensures CSS :hover styles, JavaScript hover handlers, and tooltip triggers are properly deactivated — the element returns to its non-hovered state.

drag(from, to, options?)

Simulate a click-drag from one location to another. Each endpoint can be a CSS selector (resolves to the element's center) or absolute coordinates.

ts
drag({ selector: "#item" }, { selector: "#dropzone" });
drag({ x: 100, y: 200 }, { x: 500, y: 300 });
drag({ selector: "#slider-thumb" }, { x: 800, y: 200 });

Endpoint types:

ShapeTypeResolves to
Selector{ selector: string }Center of the matching DOM element.
Coordinates{ x: number; y: number }Absolute viewport position.
OptionTypeDefaultDescription
cursorPartial<CursorConfig>Per-step cursor override.

Default duration is 1000 ms (15% move to source, 5% press, 70% drag, 10% release). Dispatches standard pointer and mouse events (pointerdown, mousemove, pointerup, etc.), not the HTML5 Drag and Drop API.

clearCache()

Clear the browser cache inside the iframe. Useful at the start of a walkthrough to ensure a clean state.

ts
clearCache();

No options. Default duration is 50 ms.


Composers

Composers combine multiple steps into a single logical unit.

sequence(...steps)

Run steps one after another. The total duration is the sum of all child durations.

ts
import { sequence, moveTo, click, wait } from "@walkrstudio/core";

sequence(
  moveTo("#btn", { duration: 400 }),
  click("#btn"),
  wait(300),
);

parallel(...steps)

Run steps simultaneously. The total duration is the maximum of all child durations.

ts
import { parallel, moveTo, narrate } from "@walkrstudio/core";

parallel(
  moveTo("#hero", { duration: 1000 }),
  narrate("/audio/intro.mp3", { duration: 1000 }),
);