From merge-movies
Create reusable React animation templates (snippets) for the merge.mov template library.
How this skill is triggered — by the user, by Claude, or both
Slash command
/merge-movies:create-react-templateThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Create reusable React animation templates (snippets) for the merge.mov template library.
Create reusable React animation templates (snippets) for the merge.mov template library.
$ARGUMENTS
This skill creates standalone React animation templates that can be reused across movies. Templates are saved to the user's personal snippet library and can be shared with all Merge Movies users.
/merge-movies:create-react-template animated progress bar - Create from a description/merge-movies:create-react-template - Interactive modeThis skill uses the merge-movies MCP server. Authentication is handled automatically via OAuth.
| Tool | Description |
|---|---|
list_react_templates | Search existing templates by keyword or tags |
get_react_template | Get full code of an existing template |
create_react_template | Save a new template to the user's library |
Parse $ARGUMENTS to understand what kind of animation template the user wants. If unclear, ask. Common categories:
Call list_react_templates to check if a similar template already exists:
query for keyword search (e.g. "diagram", "progress")tags for category filtering (e.g. ["diagram", "architecture"])If a close match exists, call get_react_template to get the full code and use it as a starting point. Customize rather than rewrite.
The code field is the body of a React function component that receives a scope object with Remotion APIs.
Available via scope:
Core Remotion:
React — the React libraryuseCurrentFrame() — current frame number (0-indexed)useVideoConfig() — returns { fps, durationInFrames, width, height }spring({ frame, fps, config? }) — physics-based animation (0->1). Config: damping, mass, stiffness, overshootClampinginterpolate(value, inputRange, outputRange, options?) — map values between ranges. Options: { extrapolateLeft, extrapolateRight } with 'clamp'|'extend'|'wrap'Easing — easing curves for interpolate: Easing.bezier(), Easing.ease, Easing.inOut(), etc.interpolateColors(frame, inputRange, colorRange) — smooth color transitions (hex/rgb/rgba)random(seed) — deterministic random number (0-1), safe for Remotion (same value per frame)Sequence — render children during a frame range. Props: from, durationInFramesSeries — sequential Sequence blocks. Children: <Series.Sequence durationInFrames={n}>AbsoluteFill — full-screen absolutely-positioned containerLoop — loop children for N iterations. Props: durationInFrames, timesFreeze — freeze animation at a specific frame. Props: frameImg — Remotion image componentVideo — Remotion video componentAuthenticatedVideo — video component with auth token supportuseAuthenticatedImage(url) — returns authenticated image URL for private assetsShapes (@remotion/shapes — SVG shape components with built-in stroke animation):
Circle — Props: radius, fill, stroke, strokeWidth. All shapes support strokeDasharray/strokeDashoffset for draw-on animationRect — Props: width, height, cornerRadius, fill, strokeStar — Props: innerRadius, outerRadius, points, fill, strokeTriangle — Props: length, direction, fill, strokeEllipse — Props: rx, ry, fill, strokePie — Props: radius, progress (0-1), fill, closePathHeart — Props: width, fill, strokePolygon — Props: radius, points, fill, strokePaths (@remotion/paths — SVG path animation):
evolvePath(progress, path) — returns strokeDasharray + strokeDashoffset to animate path drawing from 0 to 1getPointAtLength(path, length) — get {x, y} coordinates at a distance along a pathgetLength(path) — total length of an SVG path stringinterpolatePath(progress, path1, path2) — morph between two SVG pathsparsePath(d) — parse an SVG path d string into instructionsresetPath(path) — translate a path so its bounding box starts at (0,0)scalePath(path, scaleX, scaleY?) — scale a pathtranslatePath(path, x, y) — translate a pathgetBoundingBox(path) — get {x1, y1, x2, y2} of a pathgetSubpaths(path) — split compound path into individual subpathsNoise (@remotion/noise — Perlin noise for organic effects):
noise2D(seed, x, y) — 2D Perlin noise (-1 to 1). Use for flowing backgrounds, wave effectsnoise3D(seed, x, y, z) — 3D noise (use frame as z for animated noise fields)noise4D(seed, x, y, z, w) — 4D noiseAnimation Utils (@remotion/animation-utils):
makeTransform([translateY(10), scale(1.5), rotate(45)]) — compose CSS transforms safely (avoids string interpolation bugs)interpolateStyles(frame, inputRange, { opacity: [0, 1], transform: ['scale(0)', 'scale(1)'] }) — interpolate entire style objectsTransitions (@remotion/transitions — within-scene transitions between content):
TransitionSeries — like Series but with transitions between children. Children: <TransitionSeries.Sequence> and <TransitionSeries.Transition>springTiming({ config? }) — spring-based transition timinglinearTiming({ durationInFrames }) — linear transition timingtransitionFade() — cross-fade presentationtransitionSlide({ direction? }) — slide presentation. Direction: 'from-left'|'from-right'|'from-top'|'from-bottom'transitionWipe({ direction? }) — wipe presentationtransitionFlip({ direction? }) — 3D flip presentationtransitionClockWipe() — clock wipe presentationLayout Utils (@remotion/layout-utils):
measureText({ text, fontFamily, fontSize, fontWeight? }) — returns { width, height } of rendered textfitText({ text, withinWidth, fontFamily, fontWeight? }) — returns { fontSize } that fits text within a widthCode rules:
useCurrentFrame), not time-based or statefuluseVideoConfig() for width/height — do not hardcode 1920/1080extrapolateLeft: 'clamp' and extrapolateRight: 'clamp' on interpolations→ not \u2192)#0d1117, text #e6edf3, accent #58a6ffQuality guidelines:
spring() for organic motion, interpolate() for precise controldisplay: 'flex', flexDirection: 'column', justifyContent: 'center' on the root AbsoluteFill to center content, or justifyContent: 'space-between' with padding to distribute across the full height. Horizontally: spread elements across the full width — cards in a row should span the available space with even gaps.Call create_react_template with:
name: Clear, descriptive (e.g. "Animated Timeline", "Hub-and-Spoke Diagram")description: What it visualizes and when to use it (1-2 sentences)code: The React component bodytags: 2-4 tags for discoverability. Use existing tag conventions:
diagram, list, data, text, progress, chartanimation, stagger, spring, gradientarchitecture, flow, overview, comparisonTell the user the template was created and they can view/preview it at /snippets in the app. If they want a portrait version too, offer to create a second template with the portrait tag and layout adjusted for 1080x1920.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub marked-gold/merge-movies-claude-code --plugin merge-movies