Criando Vídeos com Claude Code e Remotion
Guia de Claude Code e Remotion para gerar MP4 a partir de prompts, entender a matemática de frames, corrigir sequences e depurar renders no Studio.
Claude Code com a skill do Remotion é um fluxo de trabalho para gerar vídeos a partir de prompts em linguagem natural: instale a skill, crie o scaffolding de um projeto Remotion, descreva o vídeo em português simples e deixe o Claude escrever React com precisão de frames que renderiza para MP4. Esse é o ciclo completo. O atrito nunca está no prompt — está em compreender o código que o Claude entrega bem o suficiente para corrigi-lo quando a saída renderizada diverge do que você pediu. Este artigo percorre um exemplo voltado ao desenvolvedor do início ao fim e, em seguida, mostra como interpretar o modelo mental do Remotion para que você possa diagnosticar uma renderização com problema a partir da prévia no Studio, em vez de re-promtar às cegas.
Principais Conclusões
- Remotion é um framework React que renderiza vídeo tratando cada frame como uma função pura de um número de frame, acessado via
useCurrentFrame(), e capturando screenshots dessa saída para produzir um MP4. - A 30fps, um vídeo de 15 segundos possui 450 frames; toda animação é um mapeamento do número de frame para um valor CSS, sem nenhum editor de timeline envolvido.
- O comando de instalação apareceu em diversas formas em tutoriais — verifique o atual em
remotion.dev/docs/ai/claude-codeantes de executá-lo, pois as ferramentas de skills estão em constante mudança. - Quando animações disparam simultaneamente na prévia, a causa é quase sempre a ausência de offsets
fromnos componentes<Sequence>, que por padrão iniciam no frame 0. - O Remotion renderiza lançando o Chromium em modo headless e capturando screenshots de cada frame, o que explica por que uma composição de 30 segundos a 30fps exige 900 screenshots e por que o Remotion Lambda existe para pipelines em produção.
O que é essa stack
Remotion é um framework React de código aberto para criar vídeos programaticamente: você define cenas como componentes React, controla o timing com números de frame e renderiza a saída como MP4, WebM ou GIF — sem editor de timeline, sem arrastar e soltar. A skill do Remotion para Claude Code é um pacote de regras que ensina ao agente a superfície de API do Remotion — composições, sequências, interpolate(), spring(), configuração de renderização — para que ele gere cálculos de frame corretos em vez de adivinhar. Não se trata de um plugin que executa em tempo de renderização; é um contexto injetado no Claude para que o código que ele escreve compile e anime da forma que você descreveu.
Qual é o modelo mental do Remotion?
No Remotion, seu vídeo é uma função pura de um número de frame. Uma composição é um componente React com uma duração fixa em frames. A 30fps, um vídeo de 15 segundos possui 450 frames, e toda animação é expressa como um mapeamento do frame atual para um valor CSS — opacidade, transform, cor. Não existe timeline; existe apenas matemática.
Quatro primitivas sustentam todo o modelo, todas documentadas nos fundamentos do Remotion:
useCurrentFrame()retorna o frame sendo renderizado no momento. Seu componente é re-executado para cada frame.- fps e duration residem na
<Composition>. Conforme a documentação de composições, você definedurationInFrames,fps,widtheheightali. <Sequence>desloca o tempo. Um filho encapsulado em<Sequence from={90}>vê o frame 0 quando o frame global é 90, que é como você escalona cenas.interpolate()mapeia um intervalo de frames para um intervalo de valores.
Cálculos de frame que você usará constantemente:
| Duração | Frames a 30fps |
|---|---|
| 5s | 150 |
| 10s | 300 |
| 15s | 450 |
| 30s | 900 |
| 60s | 1800 |
Assim que você internalizar “frame como entrada, valor CSS como saída,” o código gerado deixa de parecer mágica.
Pré-requisitos e instalação
Discover how at OpenReplay.com.
Você precisa do Node.js (verifique o requisito de versão na página de introdução do Remotion antes de instalar) e do Claude Code, o agente de codificação em terminal da Anthropic. O Claude Code opera com uma assinatura Claude ou cobrança via API — confirme os requisitos de acesso atuais na documentação do Claude Code da Anthropic, pois a disponibilidade dos planos muda com frequência.
Agora a parte que todo tutorial passa rápido demais. O comando de instalação da skill do Remotion apareceu em pelo menos três formatos diferentes em publicações recentes (npx @anthropic-ai/skills add remotion, npx skills add remotion, npx skills add remotion-dev/skills). O empacotamento das skills está em evolução, portanto não confie em um comando copiado. Abra a página oficial de skills — remotion.dev/docs/ai/skills — e execute o que estiver listado atualmente. Trate essa página como a única fonte de verdade até que o ecossistema se estabilize.
Verifique primeiro se o Claude Code está no seu PATH:
claude --version
Em seguida, instale a skill usando o comando da página de documentação oficial e confirme que foi carregada perguntando ao Claude dentro de um projeto: “Do you have the Remotion skill loaded?”
Um exemplo prático: um clipe de apresentação de funcionalidade de 15 segundos
Os casos de uso mais fortes para desenvolvedores nessa stack são assets que você regenera a partir de dados ou em um cronograma: um clipe de changelog construído a partir de CHANGELOG.md, um diagrama de arquitetura animado que reflete o sistema atual, ou uma apresentação de funcionalidade de produto re-renderizada a cada release. Vamos construir a apresentação de funcionalidade.
Passo 1 — Scaffolding
O comando de scaffolding está documentado na página de introdução do Remotion:
npx create-video@latest feature-reveal
cd feature-reveal
npm install
Crie o projeto com um template ou configuração TypeScript. O scaffolding fornece src/Root.tsx (onde as composições são registradas) e uma composição inicial.
Passo 2 — Prompting no Claude Code
Abra o agente no projeto e seja explícito sobre os cálculos de frame — é aqui que a maioria das saídas ruins se origina:
Create a Remotion composition called FeatureReveal.
- 15 seconds at 30fps (450 frames), 1920x1080.
- Dark background (#0d1117).
- A headline "Ship changelogs as video" fades in over frames 0-30,
holds, then fades out over frames 420-450.
- Three feature rows below the headline, each sliding up from 40px
with a spring, staggered: row 1 enters at frame 60, row 2 at 90,
row 3 at 120.
- Register FeatureReveal in Root.tsx with the correct
durationInFrames and fps.
Passo 3 — Lendo o código gerado
Uma geração correta se parece com isto. O headline usa interpolate(); as linhas usam offsets <Sequence from> combinados com spring():
import {
AbsoluteFill,
interpolate,
spring,
Sequence,
useCurrentFrame,
useVideoConfig,
} from "remotion";
const features = ["One prompt", "Re-render per release", "Version-controlled"];
const FeatureRow: React.FC<{ label: string }> = ({ label }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
// spring() returns 0→1; we map it to translateY and opacity.
const enter = spring({ frame, fps, config: { damping: 14 } });
const translateY = interpolate(enter, [0, 1], [40, 0]);
return (
<div style={{ opacity: enter, transform: `translateY(${translateY}px)` }}>
{label}
</div>
);
};
export const FeatureReveal: React.FC = () => {
const frame = useCurrentFrame();
// Headline opacity: in by frame 30, hold, out from 420 to 450.
const headlineOpacity = interpolate(
frame,
[0, 30, 420, 450],
[0, 1, 1, 0],
{ extrapolateRight: "clamp" }
);
return (
<AbsoluteFill style={{ backgroundColor: "#0d1117", color: "white" }}>
<h1 style={{ opacity: headlineOpacity, fontSize: 72 }}>
Ship changelogs as video
</h1>
{features.map((label, i) => (
// Each row starts 30 frames after the last via `from`.
<Sequence key={label} from={60 + i * 30}>
<FeatureRow label={label} />
</Sequence>
))}
</AbsoluteFill>
);
};
A linha que vale memorizar é o interpolate() do headline. A chamada mapeia números de frame para opacidade: no frame 0 a opacidade é 0, no frame 30 é 1, mantém-se até o frame 420 e então vai a 0 até o frame 450. O array de frames e o array de valores devem ter o mesmo comprimento, e { extrapolateRight: "clamp" } impede que o valor continue além do último ponto — o nome da opção e seu comportamento estão documentados na referência do interpolate().
O escalonamento vem de from={60 + i * 30} em cada <Sequence>. Como cada linha é sua própria sequência, seu useCurrentFrame() é redefinido para 0 no frame de início, fazendo com que spring() dispare a partir do ponto de entrada da linha, e não do início do vídeo.
O Claude também deve registrar a composição em Root.tsx:
import { Composition } from "remotion";
import { FeatureReveal } from "./FeatureReveal";
export const RemotionRoot: React.FC = () => (
<Composition
id="FeatureReveal"
component={FeatureReveal}
durationInFrames={450}
fps={30}
width={1920}
height={1080}
/>
);
Se durationInFrames e fps aqui divergirem dos números de frame no seu componente, o timing quebra. Essa é a causa mais comum de “o vídeo tem a duração errada.”
Passo 4 — Prévia no Studio
Inicie o Remotion Studio:
npm run dev
O Studio abre no seu navegador (observe a porta que ele exibe — nem sempre é a mesma). Selecione FeatureReveal, pressione play e arraste o playhead. Arrastar para um frame específico é o movimento central de depuração: a prévia mostra exatamente o que o frame N renderiza, permitindo que você compare com os cálculos de frame no seu código.
Como diagnosticar uma renderização do Remotion que parece errada?
Diagnostique a partir da prévia no Studio, não a partir de uma lista genérica de erros. Arraste até o frame onde o problema aparece e leia o código que controla aquele intervalo de frames. Três modos de falha respondem pela maioria dos casos.
Tudo anima ao mesmo tempo. Quando as animações disparam simultaneamente na prévia, a causa é quase sempre a ausência de offsets from nos componentes <Sequence>: cada cena começa no frame 0 por padrão, a menos que você defina from={startFrame}. Arraste até o frame 0 — se as três linhas já estão em movimento, as sequências não estão escalonadas. Corrija pedindo: “Wrap each feature row in its own <Sequence> with from set to 60, 90, and 120.”
O vídeo tem a duração errada. O Claude gera números de frame a partir do fps que você informa. Se você não especificar o fps, ele assume um padrão e pode calcular incorretamente em relação a uma composição configurada de forma diferente. Arraste até o final do playhead: se sua animação de 450 frames termina no frame 300, o durationInFrames da composição está definido como 300. Re-prompt com os números exatos — “15 seconds at 30fps is 450 frames; set durationInFrames={450}” — em vez de algo vago como “make it longer.”
O movimento parece robótico. interpolate() linear sem easing parece mecânico. Arraste por uma animação de entrada: se ela se move em velocidade constante, não há easing. Substitua por spring() para um movimento orgânico (ele retorna um valor de 0→1 que você mapeia em um transform), ou passe uma opção easing para interpolate() conforme a documentação do interpolate. Peça: “Use spring() for the row entry instead of a linear interpolate.”
Replays de sessão de vídeos de demonstração incorporados em landing pages frequentemente revelam um modo de falha separado — autoplay de um MP4 grande que bloqueia a renderização da página — mas isso é uma preocupação de entrega, não de renderização.
Renderizando para MP4
Renderize pela linha de comando com npx remotion render, passando o id da composição e um caminho de saída:
npx remotion render FeatureReveal out/feature-reveal.mp4
Aqui está a realidade que os prompts de tutoriais ignoram. O Remotion renderiza lançando o Chromium em modo headless, capturando screenshots de cada frame e passando os frames pelo ffmpeg — a arquitetura está descrita na documentação de renderização. Uma composição de 30 segundos a 30fps significa 900 screenshots do navegador. É por isso que o tempo de renderização escala com a contagem de frames e a complexidade por frame, e por que uma composição longa ou visualmente pesada pode levar um tempo considerável em um laptop, em vez de renderizar “em menos de um minuto.”
Para pipelines em produção — vídeos longos, muitas variantes, CI que não pode monopolizar um agente de build — o caminho em nuvem documentado do Remotion é o Remotion Lambda, que distribui os frames entre funções Lambda paralelas. O Lambda vale o custo de configuração assim que o tempo de renderização local se torna um gargalo ou quando você precisa renderizar em um cronograma sem a máquina de um desenvolvedor no loop. Para um clipe de 15 segundos pontual, renderize localmente e ignore o Lambda.
O Remotion é gratuito para indivíduos e pequenas empresas; empresas maiores precisam de uma licença — verifique os termos atuais na página de licença do Remotion antes de usar comercialmente.
Quando você não deve usar o Remotion?
Use o Remotion quando o vídeo for orientado a dados, repetível ou precisar corresponder exatamente a um design system — um clipe de changelog, um diagrama animado, uma apresentação de funcionalidade por release. Use um editor tradicional ou um gerador de vídeo com IA quando o conteúdo for ao vivo, fotorrealista ou uma peça criativa pontual onde o custo de iteração de re-renderização supera o benefício do controle baseado em código. Cortar erros de uma gravação com câmera, fazer color grading de footage ou produzir movimento orgânico e fotorrealista são tarefas com as quais o Remotion vai dificultar seu trabalho. A linha divisória é se a saída se beneficia de ser um programa: se você vai renderizá-la uma vez e nunca mais tocá-la, o código é sobrecarga, não uma vantagem.
O retorno dessa stack está na segunda renderização, não na primeira. Uma vez que uma composição existe, regenerá-la a partir de novos dados — um novo changelog, uma nova métrica, um novo release — é um único comando. Instale a skill a partir da página de documentação oficial, construa o exemplo de apresentação de funcionalidade acima e, em seguida, aponte a mesma composição para dados que você realmente publica.
Perguntas Frequentes
Qual é a diferença entre interpolate() e spring() no Remotion?
interpolate() mapeia um intervalo de frames para um intervalo de valores de forma linear por padrão, então você controla os frames exatos de início e fim, como fazer a opacidade ir de 0 a 1 entre os frames 0 e 30. spring() retorna um valor baseado em física de 0 a 1 que entra suavemente e se estabiliza de forma natural, que você mapeia em um transform ou opacidade. Use interpolate() para timing preciso e pausas; use spring() para movimento orgânico que deve parecer menos mecânico.
Por que meu vídeo do Remotion é mais curto ou mais longo do que eu pedi?
A duração é controlada por durationInFrames na Composition em Root.tsx, não pelos valores de animação dentro do seu componente. Se durationInFrames for 300, mas sua animação rodar até o frame 450, a renderização para no frame 300 e corta o restante. O valor de fps também deve corresponder à matemática que você usou: a 30fps, 15 segundos são 450 frames. Defina ambos explicitamente para que os cálculos do componente e a configuração da composição estejam de acordo.
Posso usar a skill do Remotion sem escrever nenhum React?
Você pode descrever vídeos em linguagem natural e deixar o Claude Code gerar o React, mas ainda precisará ler a saída para corrigi-la quando a renderização divergir do que você pediu. A skill ensina ao Claude a API do Remotion para que ele produza cálculos de frame corretos, mas não elimina a necessidade de compreender composições, sequências e números de frame ao depurar. Conhecer o modelo mental de frame como entrada e valor CSS como saída é o que permite diagnosticar problemas a partir da prévia no Studio.
Quando vale a pena configurar o Remotion Lambda em vez de renderizar localmente?
O Remotion Lambda vale o custo de configuração assim que o tempo de renderização local se torna um gargalo ou quando você precisa renderizar em um cronograma sem a máquina de um desenvolvedor no loop. Como o Remotion captura screenshots de cada frame pelo Chromium em modo headless, o tempo de renderização escala com a contagem de frames e a complexidade por frame, fazendo com que vídeos longos ou muitas variantes monopolizem um laptop ou agente de build. O Lambda distribui os frames entre funções paralelas. Para um clipe curto e pontual, renderize localmente e ignore o Lambda.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.
Star on GitHub12k