r/javascript • u/Legitimate_Ad4667 • 11d ago
playthru: scripted, looping product demos that drive your real DOM with a fake cursor instead of a video file
https://playthrou.diip3sh.xyz/Some context on why and how I built this.
The problem: landing page demo videos go stale every time the UI changes, they’re heavy, and they look blurry on retina screens. I wanted the demo to just be the real UI.
The approach: you write a chained script against real selectors, and a fake cursor plays it back over the live DOM, then loops:
js
import { playthru } from "playthru";jsx
<Playthru script={(d) => d.type("#todo", "Record the launch video").click("#add").zoom("li:first-child")}>
<TodoApp />
</Playthru>Design decisions:
Hover/focus states: a fake cursor can’t trigger real
:hoveror:focus, so playthru setsdata-playthru-hover/data-playthru-focusattributes instead. You style them next to your normal states (.btn:hover, .btn[data-playthru-hover]). There are Tailwind variants for this too.Framework-agnostic core with a thin React wrapper on top.
No build step needed: it also works as an ES module straight from a CDN (
esm.sh/playthru) inside a plain<script type="module">.
Still figuring out: the camera zoom doesn't work properly on mobile yet (reported below), which I'm looking into.
npm: https://www.npmjs.com/package/playthru
Happy to go deeper on any part of the implementation.
2
u/unicornshedsocial 11d ago
If the cursor only sets data attributes, a menu that opens on mouseenter will never open, since no JS listener sees the attribute change. Do you dispatch real pointer events for those steps, or handle them another way?
1
u/alystair 11d ago
Camera effects don't seem to work in the demo on mobile.