Introduction

Familiar shadcn components rebuilt for Remotion. You declare what state a component is in and when, and it renders that state as a pure function of the frame.

One button, four authored steps60 frames, 30 fps
  1. At frame 0Idle
  2. At frame 12Hover
  3. At frame 30Press
  4. At frame 48, duration 6Loading

What makes this different from regular shadcn

In a browser, a button enters its loading state because the user clicked. In a video, it enters that state because you authored { at: 35, state: "loading" }. The component looks identical; the wiring is completely different.

This also means you get things that are impossible in a real UI: scrub backward through a form fill, play a button click at half speed, or loop a checkbox toggle indefinitely, all without any special setup.

  • NotuseState
  • NotonClick
  • Nottransition:
  • useCurrentFrame()

Two kinds of atom

Every primitive is one of two shapes. Knowing which tells you where the frame is read and how timing reaches the component.

Read concepts

State atoms

Snap or smooth

Pure visual functions of state and theme. They never read the frame; the state comes from a prop, useCurrentState, or a transition hook like useButtonTransition.

{ at: 12, state: "hover" }

Motion atoms

Loop on the frame

Loop on useCurrentFrame() with no discrete states. No Date, no Math.random, no requestAnimationFrame, so they stay safe in the headless renderer.

<Caret blink={!tw.typing} />

Install your first primitive

Remotion must already be set up. The shared remocn-ui core installs automatically as a registry dependency, so you only name the component you want.

Installation
$ pnpm dlx shadcn@latest add @remocn/button
  • components/remocn/button.tsx
  • lib/remocn-ui/shared core

Components

The pieces a product demo is made of: a cursor that clicks, a menu that opens, a toast that lands. Each one copies into components/remocn/ with its transition hook.

34

Blocks

Complete, shippable scenes built from these primitives. Each block orchestrates the cursor, fields and feedback into one coherent story you can drop into a Sequence.

8