<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Remocn</title>
    <description>The latest articles on DEV Community by Remocn (@remocn).</description>
    <link>https://dev.to/remocn</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4038078%2F91eeefac-7966-4f15-9101-9fd4a4a5a30d.png</url>
      <title>DEV Community: Remocn</title>
      <link>https://dev.to/remocn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/remocn"/>
    <language>en</language>
    <item>
      <title>How to create videos using Claude Code</title>
      <dc:creator>Remocn</dc:creator>
      <pubDate>Sat, 01 Aug 2026 10:57:15 +0000</pubDate>
      <link>https://dev.to/remocn/how-to-create-videos-using-claude-code-35l4</link>
      <guid>https://dev.to/remocn/how-to-create-videos-using-claude-code-35l4</guid>
      <description>&lt;p&gt;&lt;a href="https://remocn.dev" rel="noopener noreferrer"&gt;Remocn&lt;/a&gt; gives you 234 copy-paste Remotion components. That solves the parts of a video — the text entrance, the whip pan, the shader background. It does not solve the assembly: what plays when, how long the beat holds, which transition hides which cut. That work is still yours, and it happens in a loop that looks like this: edit TSX, alt-tab to &lt;code&gt;remotion studio&lt;/code&gt;, scrub, notice the subtitle lands a beat late, alt-tab back, guess a frame number, repeat.&lt;/p&gt;

&lt;p&gt;Claude Code already shortens that loop — point it at a Remotion project, install &lt;a href="https://remocn.dev/docs/agents" rel="noopener noreferrer"&gt;the remocn skill&lt;/a&gt;, and it writes scenes for you. But the agent is in a terminal and the video is in a browser tab, and neither knows about the other. When something looks wrong, you describe it in words: "the logo in the second scene, the one that fades in around frame 90, it's too big." You are being a translation layer between two windows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remocn studio&lt;/strong&gt; removes the translation layer. It is a local macOS desktop app that runs the &lt;a href="https://docs.claude.com/en/api/agent-sdk/overview" rel="noopener noreferrer"&gt;Claude Agent SDK&lt;/a&gt; against a folder on your disk, compiles that folder with its own Remotion bundler, and puts the chat and the player side by side in one window. When the logo is too big, you click it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────┬─────────────────────┬──────────────┐
│ projects │ chat                │ preview      │
│          │                     │              │
│ sessions │ streamed answer     │ &amp;lt;Player&amp;gt;     │
│ (SQLite) │ + activity lines    │ + export     │
└──────────┴─────────────────────┴──────────────┘
        Tauri v2 (Rust core)  ⇄  bun sidecar
                                 ├─ Claude Agent SDK
                                 ├─ preview host (the project's webpack)
                                 └─ export (the project's renderer)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is closer to a purpose-built Claude Code GUI than to a video editor. That distinction drives everything else, so it is worth being explicit about the three decisions underneath it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude produces code, not a spec.&lt;/strong&gt; The agent writes real Remotion TSX into your folder — the same files you would have written. There is no project JSON, no timeline document, no proprietary format to export from. Close the app and you still have a normal Remotion project that opens in any editor. The accepted cost is that the preview cannot cheaply re-render props; it has to compile source the app has never seen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open any folder.&lt;/strong&gt; The app owns neither your entry point, nor your Remotion version, nor your build config. It adapts to the project instead of the project adapting to it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It uses your Claude subscription.&lt;/strong&gt; Auth is picked up from the Claude Code CLI you are already logged into. No API key, no separate OAuth, no per-token billing surprise. The cost of that is honest: the app is inert without Claude Code installed and logged in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The loop, end to end
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Opening a folder
&lt;/h3&gt;

&lt;p&gt;Point it at an existing Remotion project, or use &lt;strong&gt;New project…&lt;/strong&gt; — a vendored template expands offline (a &lt;code&gt;package.json&lt;/code&gt;, a &lt;code&gt;tsconfig.json&lt;/code&gt;, and a &lt;code&gt;src/Root.tsx&lt;/code&gt; with exactly one &lt;code&gt;&amp;lt;Composition id="Main"&amp;gt;&lt;/code&gt;), then &lt;code&gt;bun install&lt;/code&gt; streams its output into the pane while the chat is already usable. Both steps are idempotent, so a failed install offers a Retry that is safe to press after Claude has already edited the scene.&lt;/p&gt;

&lt;p&gt;Then the app checks the things it depends on but does not own: whether Claude Code is logged in, which bun is running the sidecar, whether the folder is a Remotion project, whether its dependencies are installed and agree with the lockfile, whether an entry point is registered, and — once the preview compiles — whether any composition exists and whether one of them is called &lt;code&gt;Main&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Everything that passes is silent. The checklist renders nothing at all when there is nothing to act on. Missing dependencies can be installed from the card. Only being logged out locks the composer, because that is the one failure that would otherwise happen on send — a folder that is not yet a Remotion project does not lock anything, since asking Claude to set one up is a perfectly reasonable next move.&lt;/p&gt;

&lt;h3&gt;
  
  
  Talking to it
&lt;/h3&gt;

&lt;p&gt;The composer picks a &lt;strong&gt;mode&lt;/strong&gt;, spelled the way the Agent SDK spells it: &lt;strong&gt;Auto&lt;/strong&gt; hands routine calls to Claude Code's own classifier, &lt;strong&gt;Accept edits&lt;/strong&gt; lets writes inside the project through and still stops at every command, and &lt;strong&gt;Plan&lt;/strong&gt; makes the turn read-only. Plan mode ends in a card holding the plan itself: approve it and the &lt;em&gt;same&lt;/em&gt; turn carries on building, or send it back to be revised without losing the turn. The mode belongs to the session and survives a restart.&lt;/p&gt;

&lt;p&gt;Underneath the mode sits a permission gate that decides every call reaching it. Read, Glob, Grep, Write and Edit run silently as long as every path resolves inside the opened folder. Bash always asks. Anything resolving outside the folder always asks — and "resolves" means symlinks and &lt;code&gt;..&lt;/code&gt; are expanded first, so &lt;code&gt;../../.ssh/config&lt;/code&gt; is outside the folder whatever the literal argument said.&lt;/p&gt;

&lt;p&gt;Four choices on the card: approve once, always allow this session, decline (the agent gets a message it can carry on from, not an error that ends the turn), or cancel the turn. The card sits above the composer rather than in the transcript, because an approval is a thing to answer, not a thing that happened.&lt;/p&gt;

&lt;p&gt;The composer also carries a model picker, a reasoning-effort setting from low to max, a context-window ring that fills as the session grows, and image attachments — &lt;code&gt;Cmd+V&lt;/code&gt; pastes a screenshot straight in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading what it did
&lt;/h3&gt;

&lt;p&gt;Assistant answers render as markdown — headings, lists, syntax-highlighted code — streamed with a per-word reveal, so an 85-character delta arriving every 470 ms reads as typing rather than stepping.&lt;/p&gt;

&lt;p&gt;Every tool call collapses to one compact activity line: &lt;code&gt;Edit src/Scene.tsx&lt;/code&gt;, &lt;code&gt;Bash bun run build&lt;/code&gt;, with an icon for the kind of work and its state in the icon's colour. Click it and it expands into a real line diff computed from the tool's own &lt;code&gt;old_string&lt;/code&gt;/&lt;code&gt;new_string&lt;/code&gt; — not parsed out of result text — or the command next to its output. A run of consecutive calls folds into one row showing the newest of them and a &lt;code&gt;+N&lt;/code&gt;, which makes that row a live ticker of what the agent is doing right now. Only a failure breaks a run and keeps its own row, so an error is never hidden behind a chevron.&lt;/p&gt;

&lt;p&gt;Turns keep running when you look away. Each session has its own status — running, waiting on a permission, failed — and a turn that finishes while you are elsewhere leaves an unread dot. The projects pane orders itself around that: sessions needing you float to the top of their group, a collapsed project carries a rollup for the worst state inside it, and the "Show N more" cap counts only quiet rows, so it can never hide the one thing that was asking.&lt;/p&gt;

&lt;h3&gt;
  
  
  Watching it play
&lt;/h3&gt;

&lt;p&gt;The preview pane runs &lt;strong&gt;the project's own Remotion bundler&lt;/strong&gt;, with our entry mounted instead of the Studio UI.&lt;/p&gt;

&lt;p&gt;That turned out to be a much smaller trick than it sounds. Remotion's webpack entry is an array whose last element is a parameter, and &lt;code&gt;@remotion/studio/previewEntry&lt;/code&gt; is only &lt;code&gt;Internals.waitForRoot((Root) =&amp;gt; render(&amp;lt;Studio …/&amp;gt;))&lt;/code&gt;. Studio is a UI on top of the bundler, not part of it. Taking that slot and mounting &lt;code&gt;&amp;lt;Player&amp;gt;&lt;/code&gt; gives you a pane that is ours and pixels that are Remotion's — &lt;code&gt;staticFile()&lt;/code&gt;, Tailwind, path aliases, &lt;code&gt;webpackOverride&lt;/code&gt; and every &lt;code&gt;remotion.config.ts&lt;/code&gt; setting behave exactly as they do under &lt;code&gt;remotion studio&lt;/code&gt;, because they are the same webpack.&lt;/p&gt;

&lt;p&gt;A Vite host was tried first and quietly produced 3 CSS class selectors where Remotion's bundler produced 742: &lt;code&gt;enableTailwind&lt;/code&gt; is a splice of webpack &lt;em&gt;loaders&lt;/em&gt;, and Vite falls through to the project's own PostCSS config instead.&lt;/p&gt;

&lt;p&gt;Which composition plays is &lt;code&gt;folder → Main → first&lt;/code&gt;, and the folder wins because it is the only thing you actually pointed at — opening &lt;code&gt;src/demos/launch-film&lt;/code&gt; in a project with forty compositions should not play &lt;code&gt;transition-lab&lt;/code&gt;. The pane always says which of the three rules fired.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pointing at what's wrong
&lt;/h3&gt;

&lt;p&gt;Two gestures, deliberately separate because they answer different questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inspect&lt;/strong&gt; answers &lt;em&gt;change this&lt;/em&gt;. Turn it on, hover the frame, click the element you mean, and it lands in the composer as an &lt;code&gt;[Element #N]&lt;/code&gt; token you can point at from your sentence. What Claude receives with that token is the absolute path, line and column of the JSX that rendered the node, the component that owns it, a project-only component stack, the composition, the frame you were looking at, the frame within the enclosing scene with its timing, and the node's own markup. "Make this bigger" becomes an instruction, not a riddle.&lt;/p&gt;

&lt;p&gt;Source resolution is &lt;a href="https://react-grab.com" rel="noopener noreferrer"&gt;React Grab&lt;/a&gt; driven headlessly — telemetry off, its overlay taken down entirely, the one web-font &lt;code&gt;@import&lt;/code&gt; in its stylesheet stripped when the file is served, and a test that fails if a version bump reintroduces one. The hit-testing is ours, because a picker for video needs rules a general one does not: it takes the first element that actually &lt;em&gt;paints&lt;/em&gt; at the point rather than the topmost transparent wrapper, and it climbs out of inline wrappers to the first block-level element — so clicking a word in a line animated word-by-word selects the line, not the word. An SVG is always a drawing: clicking one path selects the whole icon. Holding Alt turns every rule off and takes the literal node.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Snapshot&lt;/strong&gt; answers &lt;em&gt;look at this&lt;/em&gt;. Turn it on and the player pauses; click the frame to attach the whole thing, or drag a rectangle to attach just the part that is wrong. It arrives in the composer as an ordinary &lt;code&gt;[Image #N]&lt;/code&gt; attachment.&lt;/p&gt;

&lt;p&gt;The pixels come from &lt;code&gt;renderStill&lt;/code&gt; in &lt;strong&gt;the project's own &lt;code&gt;@remotion/renderer&lt;/code&gt;&lt;/strong&gt; — the path an export will take — so what Claude sees is what will be in the file, not what a webview happened to paint. Measured against a real project, the still is byte-identical to what &lt;code&gt;npx remotion still&lt;/code&gt; produces for the same frame in the same session.&lt;/p&gt;

&lt;p&gt;A capture takes &lt;strong&gt;83–122 ms&lt;/strong&gt;, because the render page stays open across captures. It started at 8.4 s. The navigation was the whole cost: that page pulled 19.9 MB over 71 requests, 64 of them fonts, and &lt;code&gt;selectComposition&lt;/code&gt; and &lt;code&gt;renderStill&lt;/code&gt; each did their own. Caching the composition measurement, warming the page while you are still aiming, and holding it open past the four slow steps of &lt;code&gt;renderStill&lt;/code&gt; is what turned it into a gesture that answers at the speed of a click.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting the file out
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Export&lt;/strong&gt; renders the playing composition to &lt;code&gt;out/&amp;lt;Composition&amp;gt;.mp4&lt;/code&gt; through the project's own &lt;code&gt;@remotion/renderer&lt;/code&gt;, with progress that reads &lt;em&gt;Rendering — 64/300 frames&lt;/em&gt;, then &lt;em&gt;Encoding&lt;/em&gt;, then &lt;em&gt;Combining the audio and the video&lt;/em&gt;, and a reveal in Finder at the end.&lt;/p&gt;

&lt;p&gt;There is no second bundle, and that is the feature: the preview host has already compiled this project and is already serving the render page it compiled, so the export renders from the same URL a snapshot does. A second &lt;code&gt;bundle()&lt;/code&gt; would cost another ~7 s and 1.67 GB of peak memory for a byte-identical result — and it could differ from what is on screen, which is the one thing an export must never do.&lt;/p&gt;

&lt;p&gt;Before rendering, the app reads &lt;code&gt;remotion&lt;/code&gt;, &lt;code&gt;@remotion/renderer&lt;/code&gt; and &lt;code&gt;@remotion/bundler&lt;/code&gt; out of your &lt;code&gt;node_modules&lt;/code&gt; and refuses when they disagree, naming every package that drifted. The render writes a dotfile and renames it on success, so a cancel or a failure cannot leave a half-written &lt;code&gt;Main.mp4&lt;/code&gt; that looks finished, and cannot destroy the export you made ten minutes ago. Cancelling waits for Remotion to actually stop before deleting the partial.&lt;/p&gt;

&lt;h3&gt;
  
  
  Remembering all of it
&lt;/h3&gt;

&lt;p&gt;Every conversation lives in the app's own SQLite, written by the sidecar as the events arrive. Closing the window does not throw the transcript away; reopening a session reloads its blocks, rebinds the folder and resumes the same SDK session. Only Claude Code's &lt;code&gt;session_id&lt;/code&gt; is borrowed — its transcript files are not a public contract and would break the pane on any CLI update.&lt;/p&gt;

&lt;p&gt;A folder is a first-class row, so the same project opened twice (through a symlink, say) is one history rather than two. A project whose folder has moved keeps its transcripts and collects under a &lt;em&gt;Moved or deleted&lt;/em&gt; heading, with a &lt;code&gt;Locate…&lt;/code&gt; that reconnects it instead of forking a second project. Deleting a session is undoable for a few seconds, and quitting inside that window drops the delete rather than rushing it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the agent already knows
&lt;/h3&gt;

&lt;p&gt;What makes this remocn studio and not a generic Claude Code GUI: the app bundle carries a Claude Code plugin with four skills — the vendored &lt;code&gt;remocn&lt;/code&gt;, &lt;code&gt;remotion-best-practices&lt;/code&gt; and &lt;code&gt;remotion-interactivity&lt;/code&gt;, plus one of our own, &lt;code&gt;video-lessons&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;video-lessons&lt;/code&gt; is 44 KB of production rules where every entry exists because the opposite was tried and had to be re-rendered: why text entrances travel on X and never on Y (browsers snap glyph baselines to whole device pixels, so the identical curve that ticks vertically is smooth horizontally), why a transform on a span silently forces &lt;code&gt;inline-block&lt;/code&gt; and breaks two-tone paragraphs, which &lt;code&gt;TransitionSeries&lt;/code&gt; shapes render an empty frame at a boundary. The turn's system prompt tells the agent to work from it before writing any video code, so those corrections no longer have to be pasted into a prompt by hand.&lt;/p&gt;

&lt;p&gt;Nothing is installed into your machine or your project for this. A project that ships its own copy of a bundled skill gets the plugin dropped wholesale rather than shadowed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs to run
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;macOS. Nothing in the code is macOS-specific, but that is all that is tested.&lt;/li&gt;
&lt;li&gt;Claude Code, installed and logged in, on a Pro or Max subscription.&lt;/li&gt;
&lt;li&gt;bun, resolved from your machine — the app does not bundle a runtime.&lt;/li&gt;
&lt;li&gt;A Remotion project with its dependencies installed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The current release is &lt;strong&gt;v0.0.1&lt;/strong&gt; and the app updates itself from GitHub releases: it checks once per launch, offers what it finds in the sidebar footer, and installs and restarts on request. The bundle is &lt;strong&gt;not Apple code-signed&lt;/strong&gt;, so first launch needs the usual Gatekeeper override. Updates are signed with the updater's own minisign key, which is a different thing entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;The prototype's definition of done is met — open a real project, ask for a scene, watch the edits land, approve the one Bash call it needs, see it in the player, export an mp4, no terminal. What is honestly still missing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two open bugs, both in the preview.&lt;/strong&gt; The pane sizes its stage from a hardcoded 16:9, so a 9:16 composition plays as a narrow strip with black on both sides — the pixels are right, the frame around them is not. And a compile that fails while the agent is mid-write can leave the pane stuck at &lt;code&gt;Compiling — 100%&lt;/code&gt;: the fix is a Reload button that is always present, plus announcing &lt;code&gt;ready&lt;/code&gt; again after a clean compile that follows a failed one, so the pane heals itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Export is deliberately narrow.&lt;/strong&gt; It renders h264 and every other knob comes from your &lt;code&gt;remotion.config.ts&lt;/code&gt;. Format and quality settings, a render queue and Lambda are all out of scope for now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some UI is present but inert.&lt;/strong&gt; ⌘K search, the project sort control and a Settings row are laid out and disabled rather than silently doing nothing — the shape is finished, the behaviour is not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Element references do not go stale.&lt;/strong&gt; A rebuild clears the markers and disarms Inspect, but marking individual references stale per changed file is deferred.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Windows and Linux are untested,&lt;/strong&gt; not excluded. The port should be cheap: there are no macOS-specific paths or process spawning, only macOS-specific testing.&lt;/p&gt;

&lt;p&gt;And the wider direction: this is the local half of the idea, where the agent writes real code you own. The hosted half — &lt;code&gt;studio.remocn.dev&lt;/code&gt;, a spec-driven browser editor over one generic composition — is a separate product with a separate trade-off, and neither is trying to become the other.&lt;/p&gt;

&lt;p&gt;If you want the components without the app, &lt;a href="https://remocn.dev" rel="noopener noreferrer"&gt;remocn.dev&lt;/a&gt; is a plain shadcn registry — &lt;code&gt;npx shadcn@latest add @remocn/soft-blur-in&lt;/code&gt; and it is your file.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>claude</category>
      <category>programming</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Making a launch video for Claude Opus 5</title>
      <dc:creator>Remocn</dc:creator>
      <pubDate>Fri, 24 Jul 2026 20:15:50 +0000</pubDate>
      <link>https://dev.to/remocn/making-a-launch-video-for-claude-opus-5-2jlo</link>
      <guid>https://dev.to/remocn/making-a-launch-video-for-claude-opus-5-2jlo</guid>
      <description>&lt;p&gt;Anthropic shipped Claude Opus 5 today. Nobody asked us for a video, so we made one anyway — fifty-five seconds, twelve beats, every claim on screen lifted from the launch post itself. This is the hardest kind of unofficial spot to get away with: the brand is one most people look at daily, so a color that's a shade off or a serif that isn't quite the right serif reads instantly. Nothing here is eyeballed.&lt;/p&gt;

&lt;h3&gt;
  
  
  The storyboard
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The tradeoff&lt;/strong&gt; — "Frontier intelligence" lands alone on warm paper, "Or a price you can run every day" swaps in beneath it, then both dim and lift to make room for the line that names the choice: "Until today, you picked one."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The name&lt;/strong&gt; — black stage, the real Claude spark scaling in off a rotation settle, "Claude Opus 5" landing under it with "Opus 5" one beat behind "Claude". Then the card holds dead still for a second and a half.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The promise&lt;/strong&gt; — the thesis in a single sentence, with "half the price" arriving in clay on its spoken cue, and the availability line ruled off beneath it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontier-Bench&lt;/strong&gt; — two bars grow on an asymmetric plot: Opus 4.8 in muted grey, then Opus 5 in clay past double its height, a count-up landing on the spoken "double" while the cost line falls beside it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The board&lt;/strong&gt; — four benchmark rows arrive from the right, one per cue, each a name → ratio pair with the ratio following through behind its label. One benchmark becomes a sweep.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The mechanism&lt;/strong&gt; — a dark stage and an agent transcript writing itself: the FreeCAD ask types in, three steps check off in olive, and the receipt lands in serif — "No competing model solved it in five attempts."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The outside voice&lt;/strong&gt; — Framer's line set as a hanging quote under a short clay rule, held near-still.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The bill&lt;/strong&gt; — three efficiency counters on oat, the biggest number last and in clay, attribution ruled off underneath.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alignment&lt;/strong&gt; — one claim, one number, and a held frame. The breather before the close.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The price&lt;/strong&gt; — $5 and $25 land as a pair, the pair anticipates downward and lifts to make room for "The same price as Opus 4.8", then &lt;code&gt;claude-opus-5&lt;/code&gt; arrives in clay.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The end card that eats itself&lt;/strong&gt; — the real Claude lockup holds, the spark winds up with a counter-move, then launches right and swallows the wordmark letter by letter on its way off-screen, blurring out into its own speed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The sting&lt;/strong&gt; — black. Nothing, for a full second past where the film should have ended. Then "Available today." fades up dead-center and never moves.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Director's notes
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The brand is Claude's own, down to the woff2.&lt;/strong&gt; The palette is read off claude.com's live stylesheet — the gray ramp for the stages, &lt;code&gt;--color-oat&lt;/code&gt;, &lt;code&gt;--color-olive&lt;/code&gt; for anything verified, and &lt;code&gt;--color-clay&lt;/code&gt; &lt;code&gt;#d97757&lt;/code&gt; as the one accent, spent only on the payoff word, the winning bar and the spark. The type is the three faces the site actually serves, vendored and gated behind &lt;code&gt;delayRender&lt;/code&gt; so a frame never catches the fallback mid-swap, set at the site's own scale. The spark, the wordmark and the "By Anthropic" mark are the shipped SVG paths — and for the outro the wordmark is split at its subpath boundaries into six glyphs that each keep their counter, so C-l-a-u-d-e animate independently while staying Anthropic's own letterforms. Taken apart, never redrawn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transitions are chosen by tone, not by variety.&lt;/strong&gt; Three grammars carry the whole film: a lateral slide (the outgoing scene shoved left, the incoming springing in from the right), a vertical rise, and a settle (the outgoing scene shrinking away as one group, one empty gap frame, the incoming items landing from above-1 scale). A slide hands the stage over while the content is still travelling, so the stage color has to crossfade across the slide window — gorgeous between two scenes in the same tonal world, and six frames of flat mid-grey when paper dissolves into near-black. So every big tonal jump takes the settle, whose color change happens inside the empty gap frame and lands instantly; the lateral moves ride the pairs that already share a tone. Twelve scenes, one continuous canvas, no slideshow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No scene is allowed to arrive blank.&lt;/strong&gt; The flip side of a clean hand-off: a slide gives the incoming scene a bare stage, so a scene whose first reveal starts at local frame 0 rides in as an empty card — the exact slideshow feel the cut exists to avoid. Every sliding scene pre-rolls its own clock by twelve to twenty frames, so its opening element is already on screen and moving as it arrives, while the rest of its reveals still land on their spoken cues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two properties of one element never share a curve.&lt;/strong&gt; Opacity rides a short quad ramp; transform rides a long exponential or a damped spring roughly three times its length. Stagger compresses rather than marching — &lt;code&gt;pow(i, 0.8) × base&lt;/code&gt; with a deterministic one-to-two-frame jitter — and children follow through, a check landing a few frames after its row on a looser damping. It is the difference between a slide that faded in and something that arrived.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The outro is driven by position, not by frames.&lt;/strong&gt; The spark's travel is one unbroken curve: a short counter-move to wind up, an accelerating sweep that eats the line, and a hand-off — with the slope still high — into a continuing acceleration straight off-scene. Each glyph's fate is a function of where the mark &lt;em&gt;is&lt;/em&gt;, not of what frame it is, so the bite always lands exactly as the spark passes over, whatever the curve does. The spin is one constant rate, held from launch to the last blurred frame; it survives that speed because the mark has no rotational symmetry to alias against.&lt;/p&gt;

&lt;h3&gt;
  
  
  The prompt
&lt;/h3&gt;

&lt;p&gt;The brief, as a prompt (validated against a clean project + the &lt;a href="https://remocn.dev/docs/ai/agent-skill" rel="noopener noreferrer"&gt;remocn skill&lt;/a&gt; before publishing):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I'm making an unofficial launch video for Claude Opus 5
(anthropic.com/news/claude-opus-5) with remocn (remocn.dev) in a Remotion
project — install anything you need with `npx shadcn add @remocn/&amp;lt;name&amp;gt;`.
Every claim on screen must come from that page, verbatim or cut.

Build a ~55-second, 1280×720, 30fps introducing spot in twelve beats:

1.  Tradeoff — "Frontier intelligence" lands alone on warm paper, "Or a price you can run every day" swaps in beneath it, then both dim and lift as "Until today, you picked one" lands below.
2.  Name — black stage; the real Claude spark scales in on a rotation settle, "Claude Opus 5" lands beneath with "Opus 5" one beat behind "Claude". Then hold — camera only.
3.  Promise — "It comes close to the frontier intelligence of Claude Fable 5 at half the price", with "half the price" in clay on its cue; the Max/Pro availability line ruled off beneath.
4.  Frontier-Bench — two bars on an asymmetric plot: Opus 4.8 in muted grey, then Opus 5 in clay past double its height, a count-up landing on "double" and the cost line falling beside it.
5.  Board — four benchmark rows arriving from the right, one per cue — CursorBench 3.2, ARC-AGI 3, Zapier AutomationBench, OSWorld 2.0 — each a name → ratio pair, the ratio following through behind its label.
6.  Mechanism — dark stage, an agent transcript writing itself: the FreeCAD ask types in, three steps check off in olive, and the receipt lands in serif: "No competing model solved it in five attempts."
7.  Outside voice — Framer's quote under a short clay rule, held still, attribution muted beneath.
8.  The bill — three efficiency counters on oat, the biggest number last and in clay, the Citadel and LexisNexis attributions ruled off under.
9.  Alignment — one claim, one number, then a held frame.
10. Price — "$5" and "$25" land as a pair; the pair anticipates downward and lifts to make room for "The same price as Opus 4.8"; then `claude-opus-5` in clay with "on the Claude API" beside it.
11. End card — the real Claude lockup holds, then the spark winds up with a counter-move, launches right and eats the wordmark letter by letter, flying off-screen and blurring out into its own speed.
12. Sting — black, empty for a full second past where the film should have ended, then "Available today" fades up dead-center and never moves.

Style: tokens read off claude.com's live stylesheet — #f0eee6 paper,
#faf9f5 ivory, #e3dacc oat, #141413 / #1f1e1d dark stages, #73726c muted
ink, with #d97757 clay as the ONE accent (the spark, the payoff word, the
winning bar) and #788c5d olive reserved for anything verified. Claude's
own three faces: serif for every spoken headline, sans for body and data
labels, mono for numbers, model ids and the transcript — at the site's own
type scale, sentence case, default tracking. Use the real spark and
wordmark SVG paths; split the wordmark into glyphs for the outro rather
than redrawing it.

Sequence all twelve scenes on ONE stage so the stage color is continuous
and scenes never overlap. Three transition grammars, chosen by TONE not
variety: a lateral slide (A shoved left, B springs in from the right) and
a vertical rise only between scenes that already share a tone; a settle
(A shrinks and fades as one group, one empty gap frame, B's items land
from above-1 scale) for every big tonal jump, so the color change happens
inside the gap. Pre-roll each sliding scene's internal clock by 12–20
frames so it never arrives as a blank card. A slow camera scale runs under
every scene, split across three depths. Two properties of one element
never share a curve: opacity on a short quad ramp, transform on a long
exponential or a damped spring ~3× as long; compressing stagger with a
deterministic jitter; children follow through a few frames behind their
parent. A vignette and one small clay spark hold above everything from
beat 3 to beat 10 so the cuts read as camera moves inside one film.

No letter-spacing, no uppercase, no badges, no eyebrows, no pulsing, no
install pills, no bounce as a default.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Make one for your product
&lt;/h3&gt;

&lt;p&gt;The generic recipe is &lt;a href="https://remocn.dev/docs/guides/launch-video" rel="noopener noreferrer"&gt;Launch video&lt;/a&gt;; the part that makes a spot feel like it came from inside the company — pointing your agent at the site's own tokens — is &lt;a href="https://remocn.dev/docs/guides/your-brand" rel="noopener noreferrer"&gt;Your brand&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/kTZvt_bty4A"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>llm</category>
      <category>marketing</category>
    </item>
    <item>
      <title>How to start with Remocn</title>
      <dc:creator>Remocn</dc:creator>
      <pubDate>Wed, 22 Jul 2026 16:04:59 +0000</pubDate>
      <link>https://dev.to/remocn/how-to-start-with-remocn-4dbn</link>
      <guid>https://dev.to/remocn/how-to-start-with-remocn-4dbn</guid>
      <description>&lt;p&gt;You need two things: an AI coding agent and an empty folder.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get an agent. We recommend Claude Code — also works with ChatGPT, opencode and others.&lt;/li&gt;
&lt;li&gt;Open the agent in an empty folder and paste:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set up a new Remotion video project in this folder, then install the remocn agent skill: npx skills add Remocn/remocn --yes. When you're done, start the preview studio so I can watch the video while we work.

When a browser tab opens with an empty video player, you're ready. Pick a guide and make it yours.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/B6SUjix1YkQ"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;This is the video we launched Remocn with. Eight beats, thirty-five seconds, built entirely from Remocn components. Below is everything you need to make the same video for your product.&lt;/p&gt;

&lt;h2&gt;
  
  
  The storyboard
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The pain&lt;/strong&gt; — two short lines land one after the other, naming the problem you solve.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The reveal&lt;/strong&gt; — "Meet &amp;lt;Product&amp;gt;", uncovered by a swirl of color.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The tagline&lt;/strong&gt; — your one-liner slides in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The positioning&lt;/strong&gt; — "Like X, for Y" assembles itself word by word.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The montage&lt;/strong&gt; — six fast cuts: a feature name over a different animated background each time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The value&lt;/strong&gt; — three claims stack up, line by line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The install&lt;/strong&gt; — a terminal types out your install command or call to action.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The outro&lt;/strong&gt; — your logo draws itself on, with one quiet closing line.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Your words
&lt;/h2&gt;

&lt;p&gt;This is the whole creative work — nine blanks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Product name&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two pain lines&lt;/strong&gt; — six words or fewer each; they're on screen for about two seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tagline&lt;/strong&gt; — one line&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Positioning&lt;/strong&gt; — the "Like X, for Y" sentence&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Six feature labels&lt;/strong&gt; — one or two words each&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Three value claims&lt;/strong&gt; — short, concrete, no adjectives you can't prove&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Install command or CTA&lt;/strong&gt; — whatever you want typed on screen&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Closing line&lt;/strong&gt; — e.g. "Open source, all the way down"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accent color&lt;/strong&gt; — one hex value; optional, the default lime looks good&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have a logo? Drop the SVG into the project folder and mention the file name in the prompt. No logo — your agent will use the product name as a wordmark.&lt;/p&gt;

&lt;p&gt;Struggling with the lines? &lt;a href="https://dev.to/docs/guides/words-on-screen"&gt;Words on screen&lt;/a&gt; is the cheat sheet.&lt;/p&gt;

&lt;h2&gt;
  
  
  The prompt
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I'm making a product launch video with remocn (remocn.dev).

Build a ~35-second, 1920×1080, 30fps launch video for &amp;lt;PRODUCT NAME&amp;gt; in this
Remotion project, using remocn components — install anything you need with
`npx shadcn add @remocn/&amp;lt;name&amp;gt;`:

1. Pain — two short lines, one after the other (scale-down-fade):
   "&amp;lt;PAIN LINE 1&amp;gt;" then "&amp;lt;PAIN LINE 2&amp;gt;".
2. Reveal — "Meet &amp;lt;PRODUCT NAME&amp;gt;", uncovered by a swirling shader transition
   (shader-swirl as a transition cover).
3. Tagline — "&amp;lt;TAGLINE&amp;gt;" (short-slide-right).
4. Positioning — "&amp;lt;LIKE X, FOR Y&amp;gt;", assembling word by word (kinetic-center-build).
5. Montage — six hard cuts, one per feature: a fullscreen shader background
   (color-panels, warp, mesh-gradient, voronoi, metaballs, god-rays), a dark
   scrim, and one label each: &amp;lt;SIX FEATURE LABELS&amp;gt;.
6. Value — three claims stacking line by line (line-by-line-slide):
   &amp;lt;THREE CLAIMS&amp;gt;.
7. Install — a short title beat, then a terminal line that types itself:
   `&amp;lt;INSTALL COMMAND OR CTA&amp;gt;`.
8. Outro — my logo (&amp;lt;LOGO FILE, or: use the product name as a wordmark&amp;gt;) over
   a blooming shader-smoke-ring, with a quiet closing line: "&amp;lt;CLOSING LINE&amp;gt;".

Style: warm dark background (#141318), off-white text, one accent color
&amp;lt;ACCENT COLOR&amp;gt;, Manrope. One quiet shader-simplex-noise field runs behind the
entire video with a radial scrim for readability. Transitions are shader
covers (swirl, dithering), not plain crossfades. Use my copy exactly as
written.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Directing the result
&lt;/h2&gt;

&lt;p&gt;The first cut won't be the final one — that's normal. Direct with plain sentences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"The pain lines go by too fast — hold each one longer."&lt;/li&gt;
&lt;li&gt;"Cut the montage to four beats."&lt;/li&gt;
&lt;li&gt;"Use my brand background #0B0B0F instead."&lt;/li&gt;
&lt;li&gt;"The tagline should come in from the left."&lt;/li&gt;
&lt;li&gt;"Make the outro two seconds shorter."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More directing vocabulary: &lt;a href="https://remocn.dev/docs/guides/directing-your-agent" rel="noopener noreferrer"&gt;Directing your agent&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Get the file
&lt;/h2&gt;

&lt;p&gt;Ask your agent: &lt;strong&gt;"Render the video."&lt;/strong&gt; You'll get an &lt;code&gt;.mp4&lt;/code&gt; in the project folder, ready to post.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Make a Product Demo Video in React</title>
      <dc:creator>Remocn</dc:creator>
      <pubDate>Mon, 20 Jul 2026 19:39:25 +0000</pubDate>
      <link>https://dev.to/remocn/how-to-make-a-product-demo-video-in-react-ief</link>
      <guid>https://dev.to/remocn/how-to-make-a-product-demo-video-in-react-ief</guid>
      <description>&lt;p&gt;This is a build log for a 30-second product demo video, written entirely in React and rendered to an &lt;code&gt;.mp4&lt;/code&gt; you can drop on a landing page, post to X, or attach to a Product Hunt launch. No After Effects, no screen recorder, no dragging clips around a GUI timeline. The stack is &lt;a href="https://remotion.dev" rel="noopener noreferrer"&gt;Remotion&lt;/a&gt; — the React framework that renders real video from components — and &lt;a href="https://remocn.dev" rel="noopener noreferrer"&gt;remocn&lt;/a&gt;, a shadcn-style registry of copy-paste animation and UI components built for it. We'll assemble three scenes: a hook line over an animated background, a simulated product walkthrough (the app UI rebuilt on a timeline instead of screen-recorded), and a closing scene with a live star counter and a call to action. Every scene is a React component, and the whole thing is one file tree you can re-render whenever your UI changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why build a demo video in code
&lt;/h2&gt;

&lt;p&gt;A GUI editor is faster for a one-off. A demo video is rarely a one-off: the product UI changes, the pricing changes, the headline changes, and every change means re-recording and re-cutting. When the video is React, a change is a prop edit and a re-render, and the diff lives in git next to the feature that caused it. You also skip the screen recorder entirely — instead of capturing your running app, you rebuild the parts you want to show as components, which stay crisp at any resolution and never leak a stray notification or the wrong cursor. The tradeoff is real: you write code instead of dragging clips, so this pays off when the video has a life beyond its first export. (There's a longer editor-versus-code comparison elsewhere; this article is the build.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Remotion and the components
&lt;/h2&gt;

&lt;p&gt;remocn assumes a Remotion project already exists. If you don't have one, &lt;code&gt;create-video&lt;/code&gt; scaffolds it; if you've never run the shadcn CLI here, &lt;code&gt;init&lt;/code&gt; writes a &lt;code&gt;components.json&lt;/code&gt;. Then a single &lt;code&gt;add&lt;/code&gt; pulls every component this article uses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. A Remotion project (skip if you already have one)&lt;/span&gt;
npx create-video@latest

&lt;span class="c"&gt;# 2. shadcn config (skip if you already have components.json)&lt;/span&gt;
npx shadcn@latest init

&lt;span class="c"&gt;# 3. Every component this article uses, in one run&lt;/span&gt;
npx shadcn@latest add &lt;span class="se"&gt;\&lt;/span&gt;
  @remocn/shader-mesh-gradient @remocn/staggered-fade-up &lt;span class="se"&gt;\&lt;/span&gt;
  @remocn/signup-flow @remocn/backdrop &lt;span class="se"&gt;\&lt;/span&gt;
  @remocn/whip-pan @remocn/zoom-blur &lt;span class="se"&gt;\&lt;/span&gt;
  @remocn/github-stars @remocn/soft-blur-in @remocn/confetti &lt;span class="se"&gt;\&lt;/span&gt;
  @remocn/terminal-simulator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;remocn follows shadcn's "own your code" model: &lt;code&gt;add&lt;/code&gt; copies each component's TypeScript source into your project under &lt;code&gt;components/remocn/&lt;/code&gt;, so you import them by path (&lt;code&gt;@/components/remocn/signup-flow&lt;/code&gt;) and edit them like your own files — there's no runtime dependency to track. The registry also resolves dependency chains for you. &lt;code&gt;signup-flow&lt;/code&gt; alone pulls in the remocn-ui core plus &lt;code&gt;cursor&lt;/code&gt;, &lt;code&gt;input&lt;/code&gt;, &lt;code&gt;button&lt;/code&gt;, &lt;code&gt;toast&lt;/code&gt;, &lt;code&gt;field&lt;/code&gt;, and &lt;code&gt;blur-in&lt;/code&gt;, and &lt;code&gt;whip-pan&lt;/code&gt; installs &lt;code&gt;@remotion/transitions&lt;/code&gt;, so the single command above leaves you with a working set.&lt;/p&gt;

&lt;p&gt;One licensing note, accurate at the time of writing: Remotion is source-available and free for individuals and companies of up to three people; larger companies need a paid company license. remocn itself is MIT.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up the composition
&lt;/h2&gt;

&lt;p&gt;A Remotion video is a &lt;code&gt;&amp;lt;Composition&amp;gt;&lt;/code&gt;: an id, the root component to render, a frame count, a frame rate, and a resolution. We're rendering 1920×1080 at 30 fps. Thirty seconds is 900 frames, and after accounting for the two transitions the exact number lands at 906 — here's the budget the rest of the article fills in.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scene&lt;/th&gt;
&lt;th&gt;What's on screen&lt;/th&gt;
&lt;th&gt;Frames&lt;/th&gt;
&lt;th&gt;Seconds&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1 — Hook&lt;/td&gt;
&lt;td&gt;shader background + &lt;code&gt;StaggeredFadeUp&lt;/code&gt; headline&lt;/td&gt;
&lt;td&gt;150&lt;/td&gt;
&lt;td&gt;5.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;↳ whip-pan&lt;/td&gt;
&lt;td&gt;overlaps scenes 1 and 2&lt;/td&gt;
&lt;td&gt;−26&lt;/td&gt;
&lt;td&gt;−0.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2 — Product&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;signup-flow&lt;/code&gt; simulated on a timeline&lt;/td&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;td&gt;16.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;↳ zoom-blur&lt;/td&gt;
&lt;td&gt;overlaps scenes 2 and 3&lt;/td&gt;
&lt;td&gt;−18&lt;/td&gt;
&lt;td&gt;−0.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3 — Closing&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;github-stars&lt;/code&gt; + CTA + &lt;code&gt;confetti&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;10.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;906&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;30.2&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The scene sequences sum to 950 frames; the two transitions overlap their neighbors by 26 and 18 frames, so the finished video is &lt;code&gt;950 − 44 = 906&lt;/code&gt; frames. &lt;code&gt;create-video&lt;/code&gt; already wired &lt;code&gt;registerRoot&lt;/code&gt; for you — you only edit the root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/Root.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Composition&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;remotion&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ProductDemo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./ProductDemo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RemotionRoot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Composition&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"ProductDemo"&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ProductDemo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;durationInFrames&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;906&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;fps&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1920&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1080&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ProductDemo&lt;/code&gt; is the component we build up over the next sections. Preview it live at any time with &lt;code&gt;npx remotion studio&lt;/code&gt;, where you can scrub the timeline frame by frame.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scene 1 — the hook line
&lt;/h2&gt;

&lt;p&gt;The opening has one job: state the value in a few words before anyone scrolls past. We put an animated shader behind a headline that assembles word by word. Both are remocn components, and both are deterministic — the shader freezes its own internal clock and instead reads the current frame, so the motion is a pure function of the timeline rather than wall-clock time. That's what makes a Remotion render reproducible across machines and safe to render in parallel chunks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/scenes/HookScene.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AbsoluteFill&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;remotion&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ShaderMeshGradient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/remocn/shader-mesh-gradient&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StaggeredFadeUp&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/remocn/staggered-fade-up&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HookScene&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AbsoluteFill&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ShaderMeshGradient&lt;/span&gt; &lt;span class="na"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AbsoluteFill&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;160&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;StaggeredFadeUp&lt;/span&gt;
        &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Deploy in one command"&lt;/span&gt;
        &lt;span class="na"&gt;staggerDelay&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;96&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#0b0b0f"&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;AbsoluteFill&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;AbsoluteFill&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ShaderMeshGradient&lt;/code&gt; fills the frame; the second &lt;code&gt;AbsoluteFill&lt;/code&gt; layers the headline on top. &lt;code&gt;StaggeredFadeUp&lt;/code&gt; lifts each word up by &lt;code&gt;distance&lt;/code&gt; pixels and fades it in, offsetting each next word by &lt;code&gt;staggerDelay&lt;/code&gt; frames — at 4 frames a word, a four-word line finishes assembling in well under a second. Mesh gradients render bright, so the headline uses a near-black &lt;code&gt;color&lt;/code&gt;; if you swap in a darker shader (there are 18 in the registry), flip the text to white. The typography components size themselves from &lt;code&gt;fontSize&lt;/code&gt;, so they're resolution-independent — no wrapper needed here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scene 2 — simulate the product on a timeline
&lt;/h2&gt;

&lt;p&gt;This is the scene most people reach for a screen recorder to make. Don't. Recording your running app captures whatever resolution your display happens to be, drags in real network lag, and risks a notification popping in mid-take. The alternative — the "fake app" technique — is to rebuild the slice of UI you want to show as a component and script it on the timeline. It renders retina-sharp at any output resolution, it re-renders when your real UI changes, and every take is identical.&lt;/p&gt;

&lt;p&gt;remocn ships these as scripted flows. &lt;code&gt;signup-flow&lt;/code&gt; drives a complete account-creation sequence: a cursor moves field to field, each input fills in, the submit button steps through hover → press → loading → success, and a success toast slides in — all keyed to frame numbers, not timers. You feed it your copy through props.&lt;/p&gt;

&lt;p&gt;These scene sims are authored against a 1280×720 reference so their internal pixel math stays predictable. To drop one into a 1080p composition, scale that reference up once with a small wrapper you'll reuse for the closing scene too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/Stage.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AbsoluteFill&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;remotion&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Stage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AbsoluteFill&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1280&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;720&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scale(1.5)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;AbsoluteFill&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A 1280×720 box scaled by 1.5 is exactly 1920×1080, centered. Now the scene: a soft gradient behind the scaled signup card.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/scenes/ProductScene.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AbsoluteFill&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;remotion&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SignupFlow&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/remocn/signup-flow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Stage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/Stage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ProductScene&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AbsoluteFill&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;linear-gradient(160deg, #eef2ff, #faf5ff)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SignupFlow&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Create your Rocket account"&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Start your 14-day trial — no card required"&lt;/span&gt;
        &lt;span class="na"&gt;fullName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Ada Lovelace"&lt;/span&gt;
        &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"ada@rocket.dev"&lt;/span&gt;
        &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"••••••••"&lt;/span&gt;
        &lt;span class="na"&gt;createLabel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Create account"&lt;/span&gt;
        &lt;span class="na"&gt;toastTitle&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Welcome aboard"&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Stage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;AbsoluteFill&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every string is a prop, so this becomes your product by editing the copy — no re-recording. &lt;code&gt;signup-flow&lt;/code&gt;'s scripted timeline runs about 360 frames (roughly 12 seconds), which is why Scene 2 gets 500 frames in the budget: enough to play the whole flow and hold on the completed form for a beat before the transition out. If your product is a CLI rather than a web app, swap &lt;code&gt;signup-flow&lt;/code&gt; for &lt;code&gt;terminal-simulator&lt;/code&gt;, which types commands into a console window and rolls older lines off the top — same idea, different surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stitch the scenes with TransitionSeries
&lt;/h2&gt;

&lt;p&gt;Individual scenes are just components. To cut between them with motion, wrap them in &lt;code&gt;TransitionSeries&lt;/code&gt; from &lt;code&gt;@remotion/transitions&lt;/code&gt; and drop a &lt;code&gt;TransitionSeries.Transition&lt;/code&gt; between each pair. remocn's transitions are presentation functions you hand to that element: &lt;code&gt;whipPan&lt;/code&gt; flings both scenes through the frame in a single camera whip, and &lt;code&gt;zoomBlur&lt;/code&gt; punches forward into the next scene with a blur. A transition doesn't add time — it overlaps the last frames of the outgoing scene with the first frames of the incoming one, so the finished duration is the sum of the sequences minus the sum of the transitions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/ProductDemo.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;linearTiming&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;springTiming&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@remotion/transitions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;whipPan&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/remocn/whip-pan&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;zoomBlur&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/remocn/zoom-blur&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HookScene&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./scenes/HookScene&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ProductScene&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./scenes/ProductScene&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ClosingScene&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./scenes/ClosingScene&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ProductDemo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sequence&lt;/span&gt; &lt;span class="na"&gt;durationInFrames&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HookScene&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sequence&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Transition&lt;/span&gt;
      &lt;span class="na"&gt;timing&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;linearTiming&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;durationInFrames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;presentation&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;whipPan&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;left&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sequence&lt;/span&gt; &lt;span class="na"&gt;durationInFrames&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ProductScene&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sequence&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Transition&lt;/span&gt;
      &lt;span class="na"&gt;timing&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;springTiming&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;durationInFrames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;damping&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;presentation&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;zoomBlur&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sequence&lt;/span&gt; &lt;span class="na"&gt;durationInFrames&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ClosingScene&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sequence&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;timing&lt;/code&gt; and &lt;code&gt;presentation&lt;/code&gt; props are separate on purpose: &lt;code&gt;presentation&lt;/code&gt; is the look of the move, &lt;code&gt;timing&lt;/code&gt; is its curve and length. &lt;code&gt;whipPan&lt;/code&gt; reads well on a linear ramp. &lt;code&gt;zoomBlur&lt;/code&gt; applies no internal easing of its own, so its character comes entirely from the timing function — &lt;code&gt;springTiming&lt;/code&gt; gives the punch-in a springy settle. Sequences sum to 950 frames, the two transitions overlap 44, and the result matches the 906 we set on the &lt;code&gt;&amp;lt;Composition&amp;gt;&lt;/code&gt;. &lt;code&gt;ClosingScene&lt;/code&gt; is the one piece still missing; it's next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scene 3 — social proof and the call to action
&lt;/h2&gt;

&lt;p&gt;The close does two things back to back: show that other people already use the product, then tell the viewer what to do. &lt;code&gt;github-stars&lt;/code&gt; handles the first half — a fly-through of stargazers with an odometer that counts up to the total. It renders standalone from built-in sample data, or you pass real stargazers you fetched. Like the signup sim, it targets a 1280×720 reference, so it goes through the same &lt;code&gt;Stage&lt;/code&gt; wrapper. Then a &lt;code&gt;Backdrop&lt;/code&gt; fills the frame for the CTA: &lt;code&gt;SoftBlurIn&lt;/code&gt; resolves the final line out of a blur, and &lt;code&gt;Confetti&lt;/code&gt; fires on top.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/scenes/ClosingScene.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AbsoluteFill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Sequence&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;remotion&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Backdrop&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/remocn/backdrop&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Confetti&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/remocn/confetti&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GitHubStars&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/remocn/github-stars&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SoftBlurIn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/remocn/soft-blur-in&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Stage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/Stage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;STARS_LEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ClosingScene&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AbsoluteFill&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Sequence&lt;/span&gt; &lt;span class="na"&gt;durationInFrames&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;STARS_LEN&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GitHubStars&lt;/span&gt;
          &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"rocket-dev/rocket"&lt;/span&gt;
          &lt;span class="na"&gt;totalStars&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4218&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;accentColor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#f5a623"&lt;/span&gt;
          &lt;span class="na"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"horizontal"&lt;/span&gt;
          &lt;span class="na"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"dark"&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Stage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Sequence&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Sequence&lt;/span&gt; &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;STARS_LEN&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Backdrop&lt;/span&gt;
        &lt;span class="na"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#0b0b0f&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AbsoluteFill&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SoftBlurIn&lt;/span&gt;
            &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Start building with Rocket"&lt;/span&gt;
            &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;84&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#fafafa"&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;AbsoluteFill&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Confetti&lt;/span&gt; &lt;span class="na"&gt;startFrame&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;particleCount&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;160&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;originY&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Backdrop&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Sequence&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;AbsoluteFill&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The two halves are ordinary &lt;code&gt;&amp;lt;Sequence&amp;gt;&lt;/code&gt; elements inside the scene: the star fly-through owns the first 150 frames, and the CTA owns the rest, starting at &lt;code&gt;from={STARS_LEN}&lt;/code&gt;. &lt;code&gt;Backdrop&lt;/code&gt; is remocn's background component — with &lt;code&gt;padding&lt;/code&gt;, &lt;code&gt;radius&lt;/code&gt;, and &lt;code&gt;shadow&lt;/code&gt; zeroed out it's a full-bleed fill, and if you leave those defaults on instead it wraps the content in a rounded, shadowed floating-window frame. &lt;code&gt;Confetti&lt;/code&gt;'s &lt;code&gt;startFrame&lt;/code&gt; is counted from the start of its &lt;code&gt;Sequence&lt;/code&gt;, so &lt;code&gt;10&lt;/code&gt; means ten frames after the CTA appears. It's worth calling out why the confetti looks the same on every render: each piece comes from a seeded pseudo-random generator, never &lt;code&gt;Math.random()&lt;/code&gt;, so a given &lt;code&gt;seed&lt;/code&gt; produces an identical burst every time — which is exactly what a deterministic, parallelized render needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Render to mp4
&lt;/h2&gt;

&lt;p&gt;With the root registered, one command turns the composition into a file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx remotion render ProductDemo out/demo.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That renders &lt;code&gt;ProductDemo&lt;/code&gt; at the resolution and frame count from the &lt;code&gt;&amp;lt;Composition&amp;gt;&lt;/code&gt; and writes &lt;code&gt;out/demo.mp4&lt;/code&gt;. While you're iterating on a single scene, render just its frames instead of all 906 — &lt;code&gt;npx remotion render ProductDemo out/scene2.mp4 --frames=124-624&lt;/code&gt; gives you the product scene in a fraction of the time (it starts at frame 124, since the 26-frame whip-pan overlap pulls it back from 150). When you want the full render to run somewhere other than your laptop — a CI job, or a render button inside your own app — &lt;code&gt;@remotion/renderer&lt;/code&gt; drives the identical render headlessly with &lt;code&gt;selectComposition&lt;/code&gt; then &lt;code&gt;renderMedia&lt;/code&gt;, and Remotion Lambda splits the frames into parallel chunks in the cloud for speed. Because every component here is a pure function of the frame, all of those paths produce the same pixels.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to go next
&lt;/h2&gt;

&lt;p&gt;The full catalog — 18 shaders, the rest of the camera and dissolve transitions, chart and chat sims, and the video-ready UI primitives that power the fake-app flows — lives at &lt;a href="https://remocn.dev/docs" rel="noopener noreferrer"&gt;remocn.dev/docs&lt;/a&gt;. The two most useful next stops for a demo are the &lt;a href="https://remocn.dev/docs/transitions/whip-pan" rel="noopener noreferrer"&gt;transitions&lt;/a&gt; you cut with and the &lt;a href="https://remocn.dev/docs/ui/components/button" rel="noopener noreferrer"&gt;UI primitives&lt;/a&gt; you compose your own product scenes from. Everything is MIT and on GitHub at &lt;a href="https://github.com/Remocn/remocn" rel="noopener noreferrer"&gt;github.com/Remocn/remocn&lt;/a&gt; — a star helps if this saved you an afternoon. Swap the signup sim for your product's real flow, change the copy, and the same three-scene skeleton becomes your next launch video.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Introducing Remocn Components for videos in React</title>
      <dc:creator>Remocn</dc:creator>
      <pubDate>Mon, 20 Jul 2026 19:24:17 +0000</pubDate>
      <link>https://dev.to/remocn/introducing-remocn-components-for-videos-in-react-3835</link>
      <guid>https://dev.to/remocn/introducing-remocn-components-for-videos-in-react-3835</guid>
      <description>&lt;p&gt;You shipped a product. Now you need a demo video — for the landing page, the launch post, the Product Hunt gallery. The usual options are all bad if you're a React developer: learn After Effects (a profession, not a weekend), hire an editor (a slow feedback loop that restarts every time your UI changes), or screen-record and accept whatever comes out.&lt;/p&gt;

&lt;p&gt;There's a fourth option that fits how you already work: write the video in React. &lt;a href="https://remotion.dev" rel="noopener noreferrer"&gt;Remotion&lt;/a&gt; has made that possible for years — a real &lt;code&gt;.mp4&lt;/code&gt; rendered from React components, where motion is a pure function of the current frame. What's been missing is the layer above it. Nobody wants to hand-build a typewriter effect again, tune a whip-pan's motion blur from scratch, or figure out why their WebGL background flickers in headless renders. Every Remotion project starts from zero.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://remocn.dev" rel="noopener noreferrer"&gt;Remocn&lt;/a&gt; is that layer: 234 production-ready components for Remotion, delivered the shadcn way — copied into your project as TypeScript source you own.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shadcn workflow, for video
&lt;/h2&gt;

&lt;p&gt;If you've used &lt;a href="https://ui.shadcn.com" rel="noopener noreferrer"&gt;shadcn/ui&lt;/a&gt;, you already know the model. Components aren't an npm dependency you configure through props and fight through overrides. The CLI copies the source file into your project, and from that moment it's your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx shadcn@latest add @remocn/soft-blur-in
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That drops &lt;code&gt;soft-blur-in.tsx&lt;/code&gt; into &lt;code&gt;components/remocn/&lt;/code&gt;. Want the blur to start softer, the spring to settle faster, the easing to feel different? Open the file and change it. There's no library API standing between you and the animation.&lt;/p&gt;

&lt;p&gt;The registry also carries dependency metadata: installing &lt;code&gt;whip-pan&lt;/code&gt; brings in &lt;code&gt;@remotion/transitions&lt;/code&gt; automatically, installing a scripted UI flow pulls the primitives it's built from. One command, working code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sixty seconds to a rendered video
&lt;/h2&gt;

&lt;p&gt;remocn assumes an existing Remotion project (&lt;code&gt;npx create-video@latest&lt;/code&gt; if you need one) and a &lt;code&gt;components.json&lt;/code&gt; (&lt;code&gt;npx shadcn@latest init&lt;/code&gt;, defaults are fine). After that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/Root.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Composition&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;remotion&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SoftBlurIn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/remocn/soft-blur-in&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RemotionRoot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Composition&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"HelloWorld"&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;SoftBlurIn&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;durationInFrames&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;fps&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1280&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;720&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;defaultProps&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx remotion render HelloWorld out.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two seconds of video, text resolving out of a soft blur, rendered to a file. Every component page on &lt;a href="https://remocn.dev/docs" rel="noopener noreferrer"&gt;remocn.dev&lt;/a&gt; mounts a real &lt;code&gt;@remotion/player&lt;/code&gt;, so you can scrub any animation frame by frame before installing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's in the registry
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;34 text animations.&lt;/strong&gt; Product videos are mostly words on screen, so this is the deepest section: &lt;code&gt;staggered-fade-up&lt;/code&gt;, &lt;code&gt;per-character-rise&lt;/code&gt;, &lt;code&gt;typewriter&lt;/code&gt; (with a deterministic blinking cursor), &lt;code&gt;kinetic-center-build&lt;/code&gt; (words push the line sideways while the phrase stays centered — it measures real word widths), &lt;code&gt;slot-machine-roll&lt;/code&gt;, &lt;code&gt;matrix-decode&lt;/code&gt;, &lt;code&gt;number-wheel&lt;/code&gt; and &lt;code&gt;rolling-number&lt;/code&gt; for metrics, &lt;code&gt;value-swap&lt;/code&gt; and &lt;code&gt;rolodex-flip&lt;/code&gt; for word substitutions.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/7a7P-Z4-rEk"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12 transitions.&lt;/strong&gt; Four camera moves — &lt;code&gt;whip-pan&lt;/code&gt;, &lt;code&gt;push-through&lt;/code&gt;, &lt;code&gt;focus-pull&lt;/code&gt;, &lt;code&gt;zoom-blur&lt;/code&gt; — modeled on how editors actually hide cuts, plus eight GPU dissolves (&lt;code&gt;grain-dissolve&lt;/code&gt;, &lt;code&gt;smoke-dissolve&lt;/code&gt;, &lt;code&gt;ripple-zoom&lt;/code&gt;, and friends) for texture. They're presentation functions for &lt;code&gt;@remotion/transitions&lt;/code&gt;, so they slot into a &lt;code&gt;TransitionSeries&lt;/code&gt; you may already have:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/DWfGiprEz9U"&gt;
  &lt;/iframe&gt;
&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;linearTiming&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@remotion/transitions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;whipPan&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/remocn/whip-pan&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sequence&lt;/span&gt; &lt;span class="na"&gt;durationInFrames&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SceneA&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sequence&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Transition&lt;/span&gt;
    &lt;span class="na"&gt;timing&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;linearTiming&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;durationInFrames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;presentation&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;whipPan&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sequence&lt;/span&gt; &lt;span class="na"&gt;durationInFrames&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SceneB&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sequence&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TransitionSeries&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;18 WebGL shader backgrounds.&lt;/strong&gt; Mesh gradients, god rays, metaballs, liquid metal — each wraps a shader from &lt;a href="https://github.com/paper-design/shaders" rel="noopener noreferrer"&gt;paper-design/shaders&lt;/a&gt; and adapts it for video rendering (more on why that's necessary below).&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/Mmwid7J8mnk"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;44 video-ready UI primitives.&lt;/strong&gt; Buttons, dialogs, command menus, toasts, tabs — the shadcn vocabulary, rebuilt for a timeline instead of user input. On top of them: scripted flows like &lt;code&gt;signup-flow&lt;/code&gt;, &lt;code&gt;checkout-flow&lt;/code&gt;, and &lt;code&gt;imessage-chat-flow&lt;/code&gt; that play out a complete interaction.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/ykYMx4ankGo"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;100 animated icons.&lt;/strong&gt; Lucide-derived geometry, re-authored for video: each icon draws its stroke in, then performs one action — the check pops, the bell rings. Browse them in the &lt;a href="https://remocn.dev/docs/icons/gallery" rel="noopener noreferrer"&gt;gallery&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/vcPmQH7xesI"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The rest.&lt;/strong&gt; Terminal simulators with typed commands, glassy code blocks, animated line and bar charts, GitHub-stars and X-follower cards for social proof, AI-chat mockups (Claude, ChatGPT, v0), confetti, and a &lt;code&gt;backdrop&lt;/code&gt; primitive that gives any scene a filled frame.&lt;/p&gt;

&lt;h2&gt;
  
  
  The boring hard parts are handled
&lt;/h2&gt;

&lt;p&gt;Video rendering is stricter than the browser you're used to. Remotion renders frame 47 in isolation — possibly on a different worker than frame 46, possibly out of order — and expects identical pixels every time it asks for that frame. A cursor blinking off &lt;code&gt;setInterval&lt;/code&gt;, a &lt;code&gt;Math.random()&lt;/code&gt; in a particle field, a CSS animation: all of them produce renders that flicker or desync.&lt;/p&gt;

&lt;p&gt;Every remocn component derives its motion from &lt;code&gt;useCurrentFrame()&lt;/code&gt; and nothing else. The shader backgrounds go further: a shader normally animates against a wall clock, so the wrappers freeze it and drive its frame uniform from the timeline, gating the first paint with &lt;code&gt;delayRender()&lt;/code&gt; so headless capture never grabs an uninitialized canvas. Scrubbing, looping, and multi-pass renders stay deterministic — which is exactly the class of bug you don't want to discover at render time, on a deadline.&lt;/p&gt;

&lt;p&gt;The other handled part is taste. Springs come pre-tuned, transition durations ship with sane defaults (a whip-pan lives on speed at ~26 frames; a focus-pull needs ~46 to breathe), and components render transparent so your background — a &lt;code&gt;backdrop&lt;/code&gt; fill or a shader — is one wrapper away.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop screen-recording your product
&lt;/h2&gt;

&lt;p&gt;The technique I'd point any founder to first: don't record your app, simulate it. The scripted UI flows replay a signup, a checkout, a chat conversation, a command-menu search — at retina sharpness, with a cursor that never fumbles, on a timeline you control frame by frame. When your product ships a redesign, you update props and re-render instead of re-recording every asset. That's the difference between a demo video that rots and one that lives in your repo next to the code it demos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Free, MIT, yours
&lt;/h2&gt;

&lt;p&gt;Everything above is MIT-licensed and free. There's no version to upgrade and no breaking API changes to absorb, because there's no dependency — the code lands in &lt;code&gt;components/remocn/&lt;/code&gt; and belongs to you. Remotion itself is the only prerequisite (free for individuals and companies of up to 3 people; larger companies need their &lt;a href="https://remotion.dev/license" rel="noopener noreferrer"&gt;company license&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Start here
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://remocn.dev/docs" rel="noopener noreferrer"&gt;Docs and live previews&lt;/a&gt; — every component with a scrubbable player&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://remocn.dev/docs/getting-started/installation" rel="noopener noreferrer"&gt;Installation guide&lt;/a&gt; — two commands and you're rendering&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Remocn/remocn" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; — a star helps more people find it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you build something with it, I'd genuinely like to see the result.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
