MDX file ──► Vite plugin ──► Browser Player ──► Export MP4 │ │ ├── headings = scenes ├── live preview ├── animation primitives ├── tweakpane controls └── server components └── WebCodecs rendering
# heading in your MDX becomes a Series.Sequence in Remotion.
Content before the first heading is the preamble (plays across all scenes).
Duration is set per heading. Animation primitives like Opacity, TranslateX,
and Scale animate CSS properties over frames.123456789101112131415161718--- fps: 30 bpm: 120 --- <Audio src="/soundtrack.mp3" /> # Intro duration=3s <TranslateX from={-140} to={0} duration={0.7 * FPS}> <div style={{ fontSize: 72, fontWeight: 900, color: 'white' }}>Title</div> </TranslateX> # Main duration=5s <Opacity from={0} to={1} duration={1 * FPS}> <p>Content fades in over 1 second.</p> </Opacity>
duration= propsFPS and BEAT are scope variables derived from frontmatterOpacity, TranslateX, Scale, Blur) animate one CSS property<Server> blocks render in RSC for async data fetching and AI generationLayoutTransition animates elements between scenes with FLIP@remotion/web-renderer (WebCodecs, no FFmpeg)1234567my-video/ ├── video.mdx ├── vite.config.ts ├── package.json ├── tsconfig.json ├── egaki-env.d.ts └── public/