/remotion-best-practices
Utilisez cette compétence chaque fois que vous écrivez une composition Remotion — démos vidéo animées, présentations de produits, soumissions de hackathons, présentations narrées — tout ce qui est rendu en MP4 via npx remotion render.
La compétence regroupe deux niveaux de connaissances :
- Fondamentaux de Remotion — les fichiers de règles en amont maintenus par l'équipe Remotion sur
github.com/remotion-dev/skills(compositions, animations, polices, audio, transitions, FFmpeg, sous-titres, etc.). - Règles de conception de vidéos de démonstration — leçons tirées d'un long cycle d'itération lors de la construction de la démo vskill / Skill Studio hackathon. Ce sont les règles qui, lorsqu'elles sont enfreintes, produisent un « diaporama » au lieu d'une présentation produit crédible.
Lisez les deux niveaux avant d'écrire.
Portée et applicabilité
Les règles de conception du niveau 2 ci-dessous ont été dérivées d'un projet spécifique : la démo vskill / Skill Studio hackathon (Anthropic / Claude Code « Built with Opus » hackathon, avril 2026). Elles reflètent l'apparence de ce produit — chrome Studio avec en-tête de fil d'Ariane, arborescence latérale, pages dark verified-skill.com avec polices mono, scènes de terminal, une thèse éditoriale « Inter est une daube IA, une serif distinctive est l'excellence ».
N'appliquez pas ces règles textuellement à des démos sans rapport. Une application mobile grand public, un tableau de bord financier, un jeu ou une présentation SaaS B2B aura son propre langage visuel, son propre rythme et ses propres attentes du public. Un flux « Enregistrer puis Publier », une page
verified-skill.com/queue, ou une barre latérale Studio avec des compteurs PROJET/PERSONNEL/PLUGINS est du contenu, pas de la conception.Utilisez ce niveau comme référence pour la technique sous-jacente : le motif de zoom de caméra, la discipline de ciblage du curseur, le rectangle de surbrillance serré au contenu, les transitions d'état sur place, le couplage voix off/script.ts, le pipeline rendu + amplification audio — ceux-ci se généralisent. Les constantes exactes (zoom 1,72×, centre du bouton x=1488, pilule de version v1.0.0 → v1.0.1, attribution « Modèles de niveau 1 · LLM de niveau 2 · Socket ») sont spécifiques à Skill Studio — traduisez, ne copiez pas.
Niveau 1 — Fondamentaux de Remotion
Reflète la compétence en amont remotion-best-practices sur https://github.com/remotion-dev/skills/blob/HEAD/skills/remotion/SKILL.md.
Configuration d'un nouveau projet
Lorsque vous êtes dans un dossier ou espace de travail vide sans projet Remotion existant, créez-en un en utilisant :
npx create-video@latest --yes --blank --no-tailwind my-video
Démarrer l'aperçu
Démarrez le Studio Remotion pour prévisualiser une vidéo. Le rechargement à chaud (HMR) du Studio s'effectue au fur et à mesure que les fichiers changent — vous n'avez PAS besoin d'un mécanisme preview_start séparé, et Bash run_in_background est la bonne façon de le garder actif à travers les modifications.
npx remotion studio --port=3030
Rendu
# Le point d'entrée doit être le fichier qui appelle registerRoot() (généralement src/remotion/index.ts)
npx remotion render src/remotion/index.ts <CompositionId> out/video.mp4 --concurrency=8 --log=info
Pièges courants :
- Passer
Root.tsxcomme point d'entrée → erreur : « ce fichier ne contient pas registerRoot ». Utilisezindex.ts. TransitionSeriesfait une introspection des propriétés sur les enfants directs ; ne pas envelopper les enfants dans<React.Fragment>. UtilisezflatMapretournant un tableau plat d'éléments<TransitionSeries.Sequence>et<TransitionSeries.Transition>.interpolate(trame, [a, b], …)nécessitea < bstrictement. Si vous dérivezbde constantes, vérifiez la cohérence lors de la conception du budget de scène — Remotion lève l'erreur « inputRange doit être strictement monotone croissant » sur la toute première image évaluée et l'ensemble de la composition échoue à se charger.
Vérification du rendu d'une seule image
npx remotion still <composition-id> --scale=0.25 --frame=30
Sujets couverts par les fichiers de règles en amont
(Charger à la demande depuis le dépôt de compétences en amont — github.com/remotion-dev/skills/tree/HEAD/skills/remotion/rules/.)
compositions.md— Définition des compositions, images fixes, dossiers, propriétés par défaut, métadonnées dynamiquesanimations.md—interpolate,spring, transitions, mathématiques basées sur les imagestransitions.md—@remotion/transitions(fondu, glissement, essuyage), comment les enchaîner dansTransitionSeriesassets.md—staticFile(),Img,Audio,Video, chargement de policesfonts.md—@remotion/google-fontset enregistrement local de policesaudio.md— Importation, rognage, volume, vitesse, hauteurcaptions.md,subtitles.md— Pistes de sous-titres et synchronisationffmpeg.md— Rognage, concaténation, opérations audio via FFmpegsilence-detection.md,extract-frames.md,get-audio-duration.md,get-video-duration.md— Utilitaires Mediabunnycharts.md,gifs.md,light-leaks.md,3d.md— Recettes de rendu spécialisées
Niveau 2 — Règles de conception de vidéos de démonstration
Ce sont les règles acquises au cours d'un long cycle d'itération. Considérez-les comme des valeurs par défaut, pas un polissage optionnel — la plupart d'entre elles proviennent de retours du type « ça a l'air bizarre, corrige ça » qui ont nécessité plusieurs tournées pour être résolus.
A. Fidélité à la référence
A1. Toujours utiliser la vraie référence
Si l'utilisateur dit « fais-le ressembler à la minute 2:43 de cette vidéo YouTube », extrayez l'image et étudiez-la. N'approchez pas de mémoire.
SOURCE="/Users/antonabyzov/Movies/.../Source.mov"
DEST_DIR=".specweave/.../assets/keyframes"
for t in 102 105 108 110 112; do
ffmpeg -y -ss "$t" -i "$SOURCE" -frames:v 1 -q:v 2 "$DEST_DIR/at-${t}s.jpg" -loglevel error
done
Ensuite, Lisez chaque JPG et concevez à partir de ce qui est réellement à l'écran — typographie, libellés exacts des boutons, couleurs des badges, disposition de l'arborescence latérale, positionnement de l'entrée de recherche, valeurs des compteurs (par exemple PROJET (1), PERSONNEL (0 sur 12), PLUGINS (0 sur 50), DISPONIBLE (62)).
A2. Utiliser de vrais logos et icônes, pas des approximations
- Logo Bell-badge
skill-studio-logo.png— copier dans chaque scène Studio sous forme de<Img src={staticFile("...")} />. Ne rendez pas un glyphe✷en l'appelant logo. - Icônes de fournisseurs — récupérer le vrai SVG/PNG pour Claude, Anthropic, OpenAI, OpenRouter, Ollama, LM Studio (par exemple, depuis
lobehub/static-png). Ne remplacez pas par des emoji. - Mascottes — dessiner avec des divs stylisés pour correspondre exactement à la forme. La mascotte Claude Code a un corps de couleur pêche
#e08160avec deux yeux carrés, deux petites mains-nodules sur les côtés au milieu du corps, et deux paires de jambes en dessous (▪ ▪ ▪ ▪). Pas d'art ASCII. - Chrome de fenêtre d'application — lorsque vous montrez un site web dans un « navigateur Chrome », rendez une vraie fenêtre de navigateur Chrome : coins arrondis, points de feux de circulation, navigation ‹ › ↻, barre d'URL verrouillée avec un cadenas et une vraie URL (
localhost:3000/hero, pas d'espaces supplémentaires, pas de point médian).
A3. Correspondre aux mises en page de référence YouTube pixel par pixel
Avant de reconcevoir une scène de mémoire, listez les éléments visibles dans l'image de référence et vérifiez chacun par rapport à votre sortie :
- Texte de la bannière — formulation exacte (
Soumettre les compétences pour vérification, pasSoumettre une compétence) - Ordre des onglets —
Aperçu · Modifier · Tests · Exécuter · Déclencheur · Versions - Badges de confiance —
T1 NON ANALYSÉ,Sécurité-Analysé —,Éditeur de confiance - Entrée de filtre — toujours au-dessus de
DISPONIBLEdans la barre latérale - Compteurs — maintenez-les cohérents entre les diapositives (
PERSONNEL (0 sur 12)partout, pas(11)sur une diapositive et(0 sur 12)sur une autre) - Contrôles du côté droit de l'en-tête (dans cet ordre) :
🔍 Rechercher des compétences [⌘K]·+ Nouvelle compétence·● Sélecteur de modèle·🔔 cloche
B. Zoom de caméra
B1. Le zoom de caméra se fait sur tout le canevas, pas sur une section mise à l'échelle
Ne mettez pas à l'échelle un seul panneau à l'intérieur du chrome. Enveloppez l'ensemble du chrome (barre du haut + corps) dans une div de transformation et mettez à l'échelle et déplacez celle-ci :
<div
style={{
width: "100%",
height: "100%",
transform: `translate(${cameraTx}px, ${cameraTy}px) scale(${cameraScale})`,
transformOrigin: "50% 50%",
willChange: "transform",
}}
>
{/* BARRE DU HAUT + CORPS */}
</div>
Les SVG de curseur + ondulation de clic vont à l'intérieur de ce wrapper afin qu'ils soient mis à l'échelle avec le chrome et restent collés à leur cible.
B2. Cliquer d'abord, puis zoomer
Le spectateur doit voir la cible du clic dans son contexte, puis être transporté pour la conséquence. Ordre :
image 130 le curseur s'approche du bouton
image 174 ondulation de clic
image 184 le bouton affiche « En cours… »
image 188 le zoom de la caméra commence (1.0 → 1.55+ sur ~30 images)
image 220+ zoom maintenu — la cascade de passage / les résultats / le défilement de révélation se produisent ici
Zoomer d'abord puis cliquer donne l'impression d'une diapositive de présentation. Cliquer d'abord puis zoomer donne l'impression que l'utilisateur a effectué l'action et que la caméra a suivi.
B3. Choisir une échelle qui pousse réellement le chrome hors du canevas
Un modeste 1,1× ne change presque rien. Pour que « la barre du haut quitte le haut du canevas », vous avez besoin d'au moins 1,5× combiné à une translation qui amène le point focal au centre du canevas. Calculez la cible ≥ (moitiéHauteurCanvas) / (distance du point focal à la barre du haut) — pour une ligne à y=540 et une barre du haut de 64 px, cela donne ≥ ~1,5×. Utilisez 1,55–1,85× comme valeurs par défaut pour « remplir la fenêtre d'affichage ».
C. Cibles de clic du curseur
C1. Toucher l'élément réel
Lorsque le curseur atterrit sur le mauvais bouton (+ Nouvelle compétence vs la pilule du sélecteur de modèle), le spectateur pense que la démo est cassée. Re-dérivez la cible à partir de la disposition à chaque fois — ne devinez pas les valeurs en pixels.
Pour une bande de contrôles alignés à droite avec padding: "0 22px" :
// Bord droit → 22 de marge → cloche (32) → 14 → modèle (~290) → 14 → Nouvelle compétence (~120) → 14 → Rechercher des compétences (~150)
NEW_SKILL_PILL_X = 1920 - 22 - 32 - 14 - 290 - 14 - 60 // = 1488 (centre du bouton)
FIND_PILL_X = 1920 - 22 - 32 - 14 - 290 - 14 - 120 - 14 - 75 // = 1339
Une fois que vous avez la constante, utilisez-la à la fois pour l'interpolation d'approche du curseur et pour l'interpolation de sortie du curseur afin que l'ondulation de clic atterrisse exactement sur la pilule, pas 200 px à droite de celle-ci.
C2. Mettre en surbrillance la cible à mesure que le curseur s'approche
Ajoutez une prop *Actif sur les composants d'en-tête partagés (par exemple, findActive, newSkillActive sur StudioHeader) que la scène du curseur active pour la fenêtre d'approche + clic. Le bouton obtient :
- Échelle 1,08×
- Anneau doux indigo ou violet via
box-shadow: 0 0 0 4px rgba(99,102,241,0.30) transition: all 0.15s ease
D. Surbrillances et rectangles
D1. Les rectangles de surbrillance ont la largeur du contenu, pas toute la ligne
Lorsque l'utilisateur veut un rectangle rouge autour de deux lignes de terminal, ne pas envelopper la colonne flex du parent — cela s'étend sur toute la ligne. Utilisez :
<div
style={{
display: "inline-flex",
flexDirection: "column",
alignSelf: "flex-start",
width: "fit-content",
border: "2px solid #dc2626",
borderRadius: 6,
padding: "10px 16px",
backgroundColor: "transparent",
}}
>
{/* les deux lignes, rien de plus */}
</div>
Tout ce qui devrait être à l'extérieur du rectangle (par exemple, la troisième ligne « Génération du composant… ») doit être un frère, pas un enfant.
D2. Annotations : préférer les rectangles aux ellipses
Un contour de rectangle de style dessiné à la main autour d'une ligne est perçu comme un « surligneur sur le canevas », ce que la plupart des utilisateurs veulent dire par « surligner ceci ». Une ellipse peut sembler décorative.
<svg viewBox="0 0 1000 100" preserveAspectRatio="none">
<rect
x="6" y="6" width="988" height="88" rx="6" ry="6"
fill="none"
stroke="#ea580c"
strokeWidth="3.6"
strokeDasharray="2160"
strokeDashoffset={2160 * (1 - progress)}
/>
</svg>
D3. Utiliser l'orange (#ea580c) pour « ce qui est nouveau » et le rouge (#dc2626) pour « ce qui est le bug »
La même démo peut porter les deux. Ne mélangez pas.
E. Modèles de disposition pour le chrome produit
E1. L'en-tête Studio est un seul composant partagé
Utilisez un StudioHeader.tsx avec cette disposition canonique, appelé depuis chaque scène Studio :
- Gauche : image du logo (PNG 40 × 40) + marque nominative « Skill Studio » + fil d'Ariane
[Auteur|Disponible] / [portée] / [dossier] / [compétence] - Droite : 🔍 Rechercher des compétences
[⌘K]· ✦ + Nouvelle compétence · ● Sélecteur de modèle · 🔔 Cloche
Passez breadcrumb, bellBadge, findActive, newSkillActive comme propriétés. L'en-tête de chaque scène est alors pixel-stable.
E2. La barre latérale a une entrée de filtre constante au-dessus de DISPONIBLE
Chaque barre latérale Studio — Parcourir, Mettre à jour, ÉvaluerAuteur, InstallerConsommateur, ModifierEtPublierAuteur — reçoit la même entrée Filtrer les compétences… au-dessus de l'arborescence DISPONIBLE. Pré-remplissez avec la requête contextuelle (frontend-design) sur les diapositives où l'utilisateur a déjà effectué une recherche.
E3. Largeurs et typographie de la barre latérale
- Largeur : 400 px (ou 460 px sur les diapositives avec des arborescences profondément imbriquées)
- Marge extérieure : 24–30 px
- En-têtes de groupe (
DISPONIBLE,AUTEUR) : 18–19 pt, espacement des lettres 1,6, graisse 700 - Sous-en-têtes (
COMPÉTENCES,.CLAUDE) : 15–16 pt, espacement des lettres 1,4 - Texte des lignes : 17–19 pt
- Pilule de version : 13–14 pt mono avec bordure de 1 px, rembourré 3/10
- Écarts verticaux : 12–14 px entre les sections, 22–36 px au-dessus des en-têtes de section
Les barres latérales étroites et denses ressemblent à des panneaux de paramètres. Les barres latérales larges et ouvertes ressemblent à une véritable interface utilisateur de produit.
F. Transitions d'état sur place
F1. Ne pas glisser vers la gauche entre des scènes qui devraient ressembler à un seul écran
Si « cliquer sur Installer → l'arborescence se met à jour avec la nouvelle compétence » doit être perçu comme une interaction continue :
- Définissez
transitionType: nullsur la scène suivante ou fusionnez les deux scènes en une seule - Gardez le chrome identique entre les scènes
- Animez l'élément changeant (retournement du compteur, rotation du chevron, glissement de la ligne) — ne faites pas de fondu complet
F2. Mettre fortement en évidence les nouveaux éléments
Un fond pêche + un anneau orange uni de 2 px + une ombre portée + une pilule d'appel ✓ Vient d'être installé est la bonne intensité pour « ceci vient d'atterrir ». Une teinte de fond subtile est perçue comme un état par défaut et le spectateur ne la remarque pas.
backgroundColor: "#fff5ee",
boxShadow: `0 0 0 2px ${ORANGE}, 0 8px 22px rgba(234,88,12,0.22)`,
F3. Retournements de compteur : halo pulsatant + rotation du chevron
Lorsqu'un nombre change (PROJET (0) → (1)) :
- Faites pivoter le chevron
▸ → ▼(transition de 200 ms) - Rendez un bref halo orange derrière le nombre : opacité
0,45 → 0, échelle0,4 → 2,2sur 18 images - Faites glisser les nouvelles lignes d'enfants de
translateY: -12 → 0sur 24 images
G. Modèles d'édition / modification de SKILL.md
G1. Remplacer, jamais supprimer, les champs obligatoires
Une compétence doit toujours avoir une description. Pour améliorer la description : biffer la ligne primitive en rouge, faire glisser la nouvelle description...
[le reste du contenu étant tronqué pour la traduction]