Criando Vídeos com Claude Code e Remotion
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
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.
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.
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.
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. Check our GitHub repo and join the thousands of developers in our community.