Guide

Build a Scroll-Scrubbed Landing Page with scroll-world

install scroll-world and ship a scroll-driven fly-through page

~12 min read

A terminal card on a dark green field showing the slash command that invokes the scroll-world skill.

You have seen the effect. You scroll, and instead of a page sliding upward, a camera moves: it flies toward a building, through the door, across the room, and out into the next scene, all in one unbroken take. Apple ships product pages like this. So does the Emons logistics site, which is the reference everyone points at.

The trick is smaller than it looks. Nothing is rendered in 3D in the browser. The camera move is a pre-rendered video, and scroll position is wired to the video timeline. The camera genuinely moves. Scroll only drives time.

scroll-world is an agent skill that builds that whole thing for you: it interviews you about the brand, generates the art, generates the camera flights, stitches the seams, and hands back a page. It runs in Claude Code, in Codex, and in any agent that reads SKILL.md. It is MIT licensed and free to install.

Install it

In Claude Code the plugin route is the one to use, because it wires up the slash command for you.

You type: /plugin marketplace add oso95/scroll-world
You type: /plugin install scroll-world@scroll-world
Note: Then invoke it with /scroll-world, or just describe the page you want.

For Codex, Cursor, and about twenty other agents, install through Vercel's skills CLI. It puts the same skill folder wherever your agent looks for skills.

Command: npx skills add oso95/scroll-world
Comment: or target one agent directly
Command: npx skills add oso95/scroll-world -a codex
Note: In Codex, invoke it with $scroll-world.

If you would rather see exactly what lands on disk, clone it and copy the folder yourself. This is worth doing once: reading a skill before you run it is a habit that pays off, and this skill runs shell commands that spend money.

Command: git clone https://github.com/oso95/scroll-world
Command: cp -R scroll-world/skills/scroll-world ~/.claude/skills/
Output: ~/.claude/skills/scroll-world/
File: SKILL.md: the procedure, the seam rule, the gotchas
File: references/prompts.md: intake checklist and prompt templates
File: references/pipeline.md: batch scripts for the whole chain
File: references/scrub-engine.js: the portable scroll engine
File: references/index-template.html: a minimal page that mounts it
File: references/knockout.py: background knockout for floating scenes

That is the whole skill. One procedure file and five references. The value is not code you could not write: it is the prompt templates, the batch scripts, and the seam method, which is the part that is genuinely hard to get right.

What you need installed first

This skill has more prerequisites than most, and it will stop and tell you if something is missing. Better to have them ready.

  • The Monid CLI, with an API key and a balance. This is the default video backend and renders the camera flights through Seedance 2.0, billed per clip in dollars.
  • The Higgsfield CLI, authenticated and holding credits. It renders the scene stills, provides the fallback video model, and renders the whole chain if Monid is absent.
  • ffmpeg and ffprobe, for pulling frames out of rendered clips and encoding the final files.
  • Python 3 with Pillow, for the mobile portrait canvases and the optional background knockout.
  • The Codex CLI, optional. If it is present, the scene stills can be generated through Codex instead, which bills them to a ChatGPT subscription rather than Higgsfield credits.

That last one is worth knowing about. Stills are the cheaper half of the bill, but if you already pay for ChatGPT, routing them through Codex takes them off your Higgsfield balance entirely.

What it costs

For a build with N scenes, you are paying for roughly N image generations and 2N minus 1 video generations. The video count is the one that surprises people: it is one flight per scene, plus a connector between every adjacent pair. Opting into the mobile version doubles the video count, because mobile is rendered as its own separate film.

At the defaults, a six scene chain at 1080p runs about 27 dollars of Monid billing, plus the Higgsfield credits for the stills. The skill prints an estimate and waits for you to approve it before anything generates. Approve it deliberately.

The interview comes first

Invoking the skill does not start generating. It starts asking. You will be walked through the subject and pitch, a brand kit that you can import from a URL or hand over or have proposed to you, the art direction, and the ordered list of scenes the camera visits. It also asks whether you want the mobile version, and it shows you the budget.

You type: /scroll-world
Claude announces: scroll-world
Output: What is the subject or industry, and what is the pitch?
Output: Brand kit: import from a URL, hand it over, or have one proposed?
Output: Camera style: fly-through, walkthrough, or locked isometric?
Output: List the scenes in the order the camera visits them.
Output: Render a native mobile chain as well? (doubles video generations)
Note: Costs are estimated and approved here, before anything generates.
The scene order you give here is the shape of the final film, so it is worth thinking about before you answer.

Answer the camera style question carefully. It is not a cosmetic preference. It selects the architecture, and the two architectures fail in completely different ways.

The choice that decides whether it looks right

There are two ways to move a camera through a chain of scenes, and picking the wrong one for your art direction produces a page that feels broken even though every technical step succeeded.

Architecture A is a continuous forward take. One camera glides forward, first scene to last, never reversing. Each leg starts from the actual last frame of the previous leg, so the seams match, and there are no connector clips at all. The legs are the journey. This is the right default for anything grounded, realistic, or walkthrough shaped.

Architecture B is dive-in plus aerial connector. The camera dives into a scene, then a connector clip pulls up and out, flies over the world, and drops into the next scene. This is the one the demos show off, and it is the one most write-ups describe as if it were the only option.

Architecture A has its own cost: the legs must be generated strictly in sequence, because each one needs the finished frame of the one before it. You cannot parallelize it, so it takes longer.

The one rule: seams must be frame-identical

This is the rule the whole skill is built around, and getting it wrong is the most common way these pages fail. The symptom is a visible pop between scenes.

Every generation renders slightly differently. If a connector ends on a fresh render of the kitchen, and the next dive clip starts on its own separate render of that same kitchen, the two images will not match, and the viewer sees a jump. The fix is to stop generating the boundary twice and hand over the exact pixels instead.

So the endpoints of a connector are never the original scene still. They are frames pulled out of the rendered videos on either side.

Command: ffmpeg -sseof -0.15 -i dive_i.mp4 -frames:v 1 -q:v 2 dive_i_last.png
Command: ffmpeg -ss 0 -i dive_next.mp4 -frames:v 1 -q:v 2 dive_next_first.png
Note: Now dive_i.end equals connector.start, and connector.end equals dive_next.start.
The last frame of the clip you are leaving, and the first frame of the clip you are entering.

This is also why the skill refuses to use certain video models. A model can only hold a seam if it accepts a start image and, for connectors, an end image. Models that take reference images only can condition a generation but cannot continue a shot, so they physically cannot hold a seam. That capability, not preference, is the selection rule.

The same logic explains a failure that looks mysterious: a chain that is seamless everywhere except one spot, right where you swapped in a cheaper model to save credits. Use one model for the whole chain.

Mobile is a second film, not a crop

A 16:9 clip on a tall phone shows you the middle third of every scene. Cropping a landscape film to portrait throws away the composition, which is why most scroll-driven pages look worse on the device most people will use.

If you opt in, scroll-world renders a parallel chain natively in 9:16, frame-locked against its own portrait stills. It is a real second film, which is exactly why it doubles the video generations and the cost. The engine then serves the portrait clips automatically on phones.

What actually goes wrong

The SKILL.md ships a long gotchas section, which is a good sign about a skill. These are the ones worth knowing before your first run.

  • The content filter flags innocent scenes. Interiors are the worst offenders: bedroom, pool, and spa scenes get rejected, and words like bed, pool, waterfall, wine, and swim can trip it. It is often non-deterministic, so re-rolling usually clears it. Budget extra time and credits for interior-heavy builds.
  • A seam pops. You used the original stills as connector endpoints instead of frames extracted from the rendered clips.
  • The camera seems to jump backward even though the seams match. That is architecture B doing what architecture B does. It is a direction problem, not a seam problem.
  • The video freezes at frame zero. The host is not serving byte ranges. The bundled engine uses blob URLs to sidestep this.
  • A scene renders black on iPhone but is fine on desktop. Safari will not paint a seeked frame in a muted video that has never played. The engine handles this by holding the still as a poster until the clip paints, so do not strip that behavior if you port the engine into a framework.

One more is worth calling out on its own, because it wastes an afternoon and the error message points nowhere useful. If you run the batch loops in your interactive shell on macOS, you are in zsh, where arrays start at 1. The scripts are written for bash, where they start at 0. Your connectors will silently grab the wrong scene's frames.

Command: bash chain.sh
Comment: not this: pasting the array loop into an interactive zsh prompt
Note: zsh arrays are 1-indexed, bash arrays are 0-indexed. Same script, different scene.

What you end up with

The output is a config-driven scroll engine in plain JavaScript. It builds its own DOM and injects its own styles into a container you hand it, so it drops into plain HTML, Next.js, Vue, or a page served from Python without assuming anything about your stack. It lazy loads clips, seeks through blobs, and crossfades the seams.

You also end up with a folder of generated mp4 files that are yours. Nothing phones home at runtime. The page is static.

Should you use it

Use it when the page is the pitch: a launch, a brand site, a single hero that has to do the work of a sales deck. The effect is genuinely hard to build by hand and this gets you there in an afternoon plus a render bill.

Skip it for anything where a reader is trying to get information quickly. A camera flight is a pace you are imposing on someone, and on a docs page or a pricing table that pace is a tax. The technique is not a default, and a skill that spends money per run is not something to point at a page nobody scrolls.

If you have not installed a skill from someone else's repository before, read the guide on doing that safely first. This one is a good example of why the habit matters: it is a well-built skill from a public repo, and it also runs shell commands that spend your money.

Stay updated

Get new guides in your inbox

One task, one guide, done fast. Practical Claude Code skills, zero noise.