npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@toineapps/demoux

v0.4.1

Published

Turn HTML prototypes into high-quality demo videos

Downloads

943

Readme

@toineapps/demoux

Turn HTML prototypes into high-quality demo videos using AI agent workflows.

How it works

  1. You have raw HTML files — a UI prototype, a landing page, an app mockup
  2. An agent builds a demo-ready prototype (phone frame, screen transitions, dark stage)
  3. demoux stages the final presentation context (viewport, frame fit, screenshot, metadata)
  4. An agent writes a recording script against that staged context
  5. demoux records the script in a headless browser and encodes it to MP4

Setup

npm install @toineapps/demoux
npx @toineapps/demoux

Creates:

prototypes/          ← demo-ready prototypes land here (agent output)
demos/               ← recorded MP4s land here
demoux.config.js     ← configuration
.claude/skills/      ← Claude Code agent skills
AGENTS.md            ← Codex agent entry point
AGENTS.demoux.md     ← demoux Codex workflows

Agent commands

Three skills, one per step. Each one asks if you want to continue to the next.

/demoux-prototype

| Agent | Command | |-------|---------| | Claude Code | /demoux-prototype | | Codex | "run demoux-prototype" |

Scans the project for raw HTML files, asks which one to use, asks mobile or desktop, then builds a polished self-contained prototype:

  • Dark stage background
  • Phone frame mockup (or fullscreen for desktop)
  • Smooth CSS screen transitions
  • All CDN assets (Tailwind, Inter, FontAwesome)
  • Every button wired to showScreen()

Saves to prototypes/<name>/prototype.html.

Ends by asking: "Should I stage the presentation context now?"


/demoux-script

| Agent | Command | |-------|---------| | Claude Code | /demoux-script | | Codex | "run demoux-script" |

Reads the staged screenshot/metadata and the prototype HTML, maps all screens and interactive elements, plans a compelling demo flow, and writes a complete recording script:

  • Scene comments for every section
  • Natural cursor hover before every click
  • Realistic typing delays
  • Scroll reveals for content below the fold
  • Movement authored against the final framed viewport
  • Verified selectors — every tap() checked against the HTML

Saves to prototypes/<name>/demo.script.js.

Ends by asking: "Ready to record? Which format — phone (9:16), desktop (16:9), or square (1:1)?"


demo stage

Use demo stage before writing the script whenever framing matters, especially for mobile portrait demos. It loads the prototype in the same viewport the final recording will use, applies the same presentation prep as the recorder, and writes:

  • recording/stage-<width>x<height>.png
  • recording/stage-<width>x<height>.json

This gives the agent a concrete visual context to author movement and pacing against instead of guessing from raw HTML structure alone.


/demoux-record

| Agent | Command | |-------|---------| | Claude Code | /demoux-record | | Codex | "run demoux-record" |

Asks for the output format, then runs the recorder non-interactively:

1. Phone portrait (9:16)  — Reels, Stories, TikTok
2. Desktop landscape (16:9) — YouTube, presentations
3. Square (1:1)           — Instagram, LinkedIn
4. Classic (4:3)

Runs npx @toineapps/demoux demo create --prototype ... --ratio ... and handles any failures automatically (broken selectors, blank frames, unstyled content).


CLI

You can also stage or record directly without the agent:

npx @toineapps/demoux demo stage
npx @toineapps/demoux demo create

Or with flags (skips interactive prompts — same flags the agent uses):

npx @toineapps/demoux demo stage --prototype prototypes/myapp/prototype.html --ratio 9:16
npx @toineapps/demoux demo create --prototype prototypes/myapp/prototype.html --ratio 9:16
npx @toineapps/demoux demo create --prototype prototypes/dashboard/prototype.html --ratio 16:9

Flags:

| Flag | Values | Description | |------|--------|-------------| | --prototype | relative path | Path to the prototype HTML | | --ratio | 9:16 16:9 1:1 4:3 | Output aspect ratio | | --device | phone desktop desktop-wide square | Viewport preset (if no ratio) |


How the script drives the recording

The recommended flow is: stage first, script second, record last. demo stage captures the final framed presentation context, and the agent should write demo.script.js against that artifact rather than against raw prototype structure alone.

The agent writes demo.script.js — a plain JS file with interaction calls. When demo create runs, it loads this file and executes it inside a real headless Chromium. Every call drives the actual browser. Playwright records the screen the whole time. ffmpeg trims and encodes to MP4.

/** @type {import('@toineapps/demoux').SceneScript} */
module.exports = async (ctx) => {
  const { tap, scroll, sleep, move, type, phoneCX, phoneCY, frame } = ctx;

  // ── Scene 1: Dashboard ────────────────────────────────────────────────────
  await move(phoneCX, frame.y + 100, 25);  // drift cursor toward CTA
  await sleep(800);
  await tap('#screen-dashboard button:has-text("Betalingen")', { delayAfterMs: 1000 });

  // ── Scene 2: Payments ─────────────────────────────────────────────────────
  await sleep(2000);
  await scroll('screen-payments', 300);
  await sleep(1000);
  await scroll('screen-payments', -300);
  await tap('#screen-payments .back-button', { delayAfterMs: 1000 });

  // ── Scene 3: Clean ending ─────────────────────────────────────────────────
  await sleep(2000);
};

Context API

| | Signature | Description | |-|-----------|-------------| | tap | (selector, { delayAfterMs? }) | Smooth cursor move + click | | scroll | (screenId, deltaY) | Scroll inside .screen-main | | move | (x, y, steps?) | Raw cursor movement | | type | (text, delayMs?) | Keyboard input | | sleep | (ms) | Pause | | frame | BoundingBox | Phone frame position and size | | phoneCX/CY | number | Center of phone frame | | page | Playwright Page | Escape hatch |


Configuration

demoux.config.js:

module.exports = {
  prototype: {
    dirs: ['.', 'prototypes'],       // where to scan for prototypes
    output: 'prototypes',
  },
  demo: {
    output: 'demos',
    format: 'mp4',
    viewport: { width: 1440, height: 940 },
    startTrimMs: 800,                // trim blank frames from start
    renderWaitMs: 800,               // wait after load before recording
  },
  cursor: {
    enabled: true,
    style: 'touch',                  // 'touch' (circle + ripple) | 'dot'
    ripple: true,
    movement: { steps: 30 },
    timing: { beforeClickMs: 160, afterClickMs: 700, hoverMs: 300 },
  },
}

Requirements

  • Node.js ≥ 18
  • Playwright: npm install playwright && npx playwright install chromium
  • ffmpeg: winget install ffmpeg / brew install ffmpeg

Full flow

raw HTML files (anywhere in the project)
        │
        ▼
/demoux-prototype        scan → ask mobile/desktop → build prototype
        │  "Should I write the script?"
        ▼
/demoux-script           read HTML → plan scenes → write + verify script
        │  "Ready to record? Which format?"
        ▼
/demoux-record           ask format → run CLI with flags → handle failures
        │
        ▼
demos/<name>-<timestamp>.mp4

In the recommended workflow, run demo stage between /demoux-prototype and /demoux-script so the script is authored against the final framed recording context.