Agent skill

Remotion Bits

by Marve10s in Marve10s/Better-Fullstack

Animation components and utilities for Remotion video projects.

MITAuto-check passedMedia & Creative

Install Remotion Bits

skills CLI
$ npx skills add Marve10s/Better-Fullstack --skill remotion-bits -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install Marve10s/Better-Fullstack remotion-bits --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/Marve10s/Better-Fullstack.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/remotion-bits .claude/skills/remotion-bits && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
remotion-bits
GitHub stars
752
Used in
1 other repo
Token cost
~8.2k tokens
SKILL.md length
1,386 words
Files
4 (incl. references)
Skills in repo
8
Repo updated
First seen
Licence
MIT

At a glance

Animation components and utilities for Remotion video projects.

  • Works in 9 steps: AnimatedValue → Responsive Sizing with useViewportRect → Transition Props Pattern → …
  • Building Remotion compositions with text animations
  • SKILL.md covers Imports, Core Concepts, Transform3D (Critical for… and Scene3D System (3D…, plus 2 more sections
  • Calls npx and npm; reaches unpkg.com

What it does

Remotion Bits is an agent skill from Marve10s/Better-Fullstack. Animation components and utilities for Remotion video projects. Use when building Remotion compositions with text animations, gradient transitions, particle effects, 3D scenes, or staggered motion effects. Provides example bits (complete compositions) and reusable components that can be installed via jsrepo.

Its SKILL.md is about 8.2k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including reference files (for example `references/components.md`, `references/patterns.md` and `references/utilities.md`).

It sits in Media & Creative, covering Video production. It works with Remotion and React. The repository describes itself as: Scaffold production-ready full-stack apps in TypeScript, Rust, Python, Go, and Java with a visual builder and CLI. Choose your frontend, backend, database, auth, AI, payments… The licence is MIT.

When your agent uses it

  • Building Remotion compositions with text animations
  • Gradient transitions
  • Particle effects
  • Staggered motion effects

Example prompts

  • “/remotion-bits”

Requirements

  • Node.js

Workflow steps

9 steps, taken from the step headings in SKILL.md.

  1. AnimatedValue
  2. Responsive Sizing with useViewportRect
  3. Transition Props Pattern
  4. Easing Functions
  5. Layout & Display Configuration
  6. Pre-compute All Positions
  7. Define Steps
  8. Add Step-Responsive Elements
  9. Content Inside Steps

What it can do on your machine

Read from SKILL.md and the folder at commit b03f092. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npx
    • npm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • unpkg.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Remotion Bits loads about 8.2k tokens when it runs, and up to ~20k if it reads all its reference files. Until then it costs about 81 tokens; SKILL.md has 1,386 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~81
When it runs · the whole SKILL.md, loaded when a task matches
~8.2k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~20k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from Marve10s/Better-Fullstack at commit b03f092, republished under its MIT licence (© Marve10s). 1,386 words, ~8,198 tokens.

Download SKILL.mdSave it as .claude/skills/remotion-bits/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.
name
remotion-bits
description
Animation components and utilities for Remotion video projects. Use when building Remotion compositions with text animations, gradient transitions, particle effects, 3D scenes, or staggered motion effects. Provides example bits (complete compositions) and reusable components that can be installed via jsrepo.

Remotion Bits

Animation components and utilities for building Remotion videos. The library's most powerful feature is Scene3D - a camera-based 3D presentation system (like impress.js) that enables cinematic multi-section compositions with flying camera moves, step-aware element animations, and Transform3D position management.

When building any non-trivial composition, prefer Scene3D as your foundation. It handles camera movement, timing, element positioning, and responsive layout all in one system. Individual components (AnimatedText, Particles, etc.) work best as content placed inside Scene3D steps.

Prerequisites: remotion >= 4.0, react >= 18, react-dom >= 18

bash
# Via npm
npm install remotion-bits

# Via jsrepo (copies source for customization)
npx jsrepo init https://unpkg.com/remotion-bits/registry.json
npx jsrepo add animated-text particle-system scene-3d

Imports

Everything is exported from remotion-bits:

tsx
import {
  // 3D Scene System (primary workflow)
  Scene3D, Step, Element3D, StepResponsive,
  Transform3D, Vector3,
  useScene3D, useCamera, useActiveStep,
  // Animation Components
  AnimatedText, AnimatedCounter, TypeWriter, CodeBlock,
  StaggeredMotion, GradientTransition, MatrixRain, ScrollingColumns,
  Particles, Spawner, Behavior,
  // Core
  useViewportRect,
  interpolate, Easing,
  interpolateColorKeyframes, interpolateGradientKeyframes,
  random, resolvePoint, createRect,
} from "remotion-bits";

Core Concepts

1. AnimatedValue

Most animation properties accept AnimatedValue: a static number OR an array of keyframes interpolated over the animation's duration.

tsx
opacity: 1                // Static
opacity: [0, 1]           // Animate 0→1
opacity: [0, 1, 0.5, 0]  // Multi-keyframe: 0→1→0.5→0 evenly spaced
scale: [0.8, 1]           // Scale from 80% to 100%
y: [30, 0]                // Slide up from 30px offset

Keyframes are evenly distributed across the duration. With 4 keyframes over 60 frames: frame 0→20→40→60.

2. Responsive Sizing with useViewportRect

Never hardcode pixel values. Always use viewport-relative units:

tsx
const rect = useViewportRect();
// rect.width   - composition width (e.g. 1920)
// rect.height  - composition height (e.g. 1080)
// rect.vw      - 1% of width (19.2)
// rect.vh      - 1% of height (10.8)
// rect.vmin    - min(vw, vh) - USE THIS for most sizing
// rect.vmax    - max(vw, vh)
// rect.cx, cy  - center coordinates
const { vmin } = rect;

Use vmin for font sizes, element dimensions, spacing, and padding. This ensures compositions render identically at 1920×1080, 1080×1920, 3840×2160, etc.

Understanding vmin at Common Resolutions

vmin = min(width, height) / 100. Always compute what vmin equals in pixels for your composition size before choosing multipliers.

Composition SizeAspect Ratiovmin (px)vmin * 8vmin * 10vmin * 5
1920×108016:9 landscape10.886px108px54px
1080×19209:16 portrait10.886px108px54px
1080×10801:1 square10.886px108px54px
3840×216016:9 4K21.6173px216px108px
1280×72016:9 720p7.258px72px36px
Font Size Reference (at 1920×1080, vmin = 10.8px)

Use these proven multipliers from production bits. Err on the side of LARGER, not smaller.

RoleMultiplierPixels at 1080pExample
Hero / main titlevmin * 10–15108–162pxFull-screen headline
Section headingvmin * 6–865–86pxScene3D step titles
Subheadingvmin * 4–543–54pxCard titles, counters
Body / card labelvmin * 2.5–327–32pxFeature labels, descriptions
Code / small textvmin * 1.5–216–22pxCode blocks, captions
Fine printvmin * 1–1.211–13pxCode font in dense blocks

Common mistake: using vmin * 3 for headings. At 1080p that's only 32px - fine for body text but too small for any heading. For prominent headings, start at vmin * 8 minimum.

Aspect Ratio Awareness

The aspect ratio determines which dimension is the "min" for vmin:

  • Landscape (16:9, 1920×1080): vmin is based on height (1080/100 = 10.8). Horizontal space is abundant; vertical space is limited.
  • Portrait (9:16, 1080×1920): vmin is based on width (1080/100 = 10.8). Vertical space is abundant; horizontal space is limited.
  • Square (1:1, 1080×1080): vmin = vmax = vh = vw. All directions equal.

Layout implications:

  • In landscape, full-width text can be very long - consider width: vmin * 70 or maxWidth constraints
  • In portrait, titles may need to wrap - use fewer words or smaller multipliers for width-constrained text
  • Use vmin for sizes that should scale uniformly regardless of orientation
  • Use vw/vh when sizing should follow a specific axis (e.g., full-width background: rect.width)
Element Size Reference
ElementMultiplierDescription
Card widthvmin * 50–70Floating card, info panel
Card heightvmin * 25–40Match content needs
Card border-radiusvmin * 1–2Subtle rounding
Spacing/gapvmin * 1–3Between elements
Paddingvmin * 2–4Inside containers
Particle sizevmin * 1–3Individual particle dot
Icon sizevmin * 8–12Decorative icons
3. Transition Props Pattern

Components accept a transition prop with this shape:

tsx
transition={{
  // Timing
  duration: 30,           // Duration in frames
  delay: 10,              // Delay before start
  frames: [0, 60],        // Or explicit frame range (alternative to duration)
  easing: "easeOutCubic", // Easing curve

  // Transform (all accept AnimatedValue)
  x: [30, 0],             // translateX
  y: [30, 0],             // translateY
  z: [0, 100],            // translateZ (3D)
  scale: [0.8, 1],        // uniform scale
  scaleX, scaleY,         // axis scale
  rotate: [0, 360],       // 2D rotation (degrees)
  rotateX, rotateY, rotateZ, // 3D rotation (degrees)
  skew, skewX, skewY,     // skew (degrees)
  transform: Transform3D[], // 3D transform keyframes (see Transform3D section)

  // Visual (all accept AnimatedValue)
  opacity: [0, 1],
  blur: [10, 0],          // Gaussian blur in pixels
  borderRadius: [0, 20],
  color: ["#ff0000", "#00ff00"],           // CSS color interpolation
  backgroundColor: ["#000", "#fff"],
}}
4. Easing Functions
tsx
type EasingName =
  | "linear"
  | "easeIn" | "easeOut" | "easeInOut"
  | "easeInQuad" | "easeOutQuad" | "easeInOutQuad"
  | "easeInCubic" | "easeOutCubic" | "easeInOutCubic"
  | "easeInSine" | "easeOutSine" | "easeInOutSine"
  | "easeInQuart" | "easeOutQuart" | "easeInOutQuart";

Most common: "easeOutCubic" for entries, "easeInOutCubic" for camera moves.

5. Layout & Display Configuration

CRITICAL: Bits are pre-wrapped with a layout container when displayed in the docs. The wrapper (withShowcaseFill) provides an AbsoluteFill with default styling. When building standalone compositions, you must provide this layout yourself.

The Layout Wrapper

Bits displayed in docs are automatically wrapped with:

tsx
<AbsoluteFill style={{
  backgroundColor: 'var(--color-background-dark)',  // #100f0f
  fontSize: `${config.width * 0.05}px`,             // 5% of width
  fontWeight: 700,
  color: 'var(--color-primary-hover)',               // #fcc192
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
}}>
  <Component />
</AbsoluteFill>

This means simple bits like <AnimatedText>Hello</AnimatedText> work because the wrapper centers them and provides background/color.

Building Standalone Compositions

When creating compositions for direct use (not displayed through the docs wrapper), you MUST provide your own layout:

tsx
import { AbsoluteFill } from 'remotion';

export const MyComposition: React.FC = () => {
  const rect = useViewportRect();
  const { vmin } = rect;

  return (
    <AbsoluteFill style={{
      backgroundColor: '#100f0f',
      color: '#fcc192',
      fontFamily: 'system-ui, sans-serif',
    }}>
      {/* Your content here */}
      <Scene3D perspective={1000} stepDuration={60} transitionDuration={60}>
        {/* Steps... */}
      </Scene3D>
    </AbsoluteFill>
  );
};
CSS Variables (Theming)

Bits use CSS variables for consistent theming. These are available when rendering within the docs but must be defined or replaced with literal values in standalone projects:

VariableDefault ValueUsage
--color-primary#ec8b49Accent orange
--color-primary-hover#fcc192Light orange / text color
--color-background-dark#100f0fDark background
--color-surface-dark#1c1b1aSurface/card background
--color-surface-light#343331Lighter surface
--color-border-dark#100f0fDark borders
--color-border-light#1c1b1aLight borders

In standalone projects: Replace var(--color-*) with literal hex values, or define these variables in your HTML/CSS.

Common Layout Mistakes
  1. Missing background: Content renders on transparent/white background. Always set backgroundColor on the outermost container.
  2. Missing AbsoluteFill: Scene3D and full-viewport compositions need <AbsoluteFill> from remotion as their root.
  3. Using CSS vars without defining them: var(--color-primary) resolves to nothing in a bare Remotion project. Use literal colors.
  4. Hardcoded pixel sizes: Use vmin-based sizing from useViewportRect() instead.
  5. Missing font settings: Set fontSize, fontWeight, fontFamily, and color explicitly - there are no inherited defaults in Remotion.
Three Layout Patterns

Simple (centered content, uses wrapper defaults):

tsx
// Relies on the outer wrapper for background, centering, font
export const Component = () => (
  <AnimatedText transition={{ opacity: [0, 1] }}>Hello</AnimatedText>
);

Self-contained (own background and layout):

tsx
export const Component = () => (
  <div style={{
    width: '100%', height: '100%',
    backgroundColor: '#09090b',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
  }}>
    <StaggeredMotion transition={{ scale: [0, 1], opacity: [0, 1] }}>
      {items}
    </StaggeredMotion>
  </div>
);

Full 3D scene (recommended for complex work):

tsx
export const Component = () => {
  const rect = useViewportRect();
  return (
    <AbsoluteFill style={{
      background: '#100f0f',
      color: '#fcc192',
    }}>
      <Scene3D perspective={1000} stepDuration={60} transitionDuration={60}>
        <Step id="intro" {...positions.base.toProps()} />
        {/* ... */}
      </Scene3D>
    </AbsoluteFill>
  );
};

Transform3D (Critical for Complex Scenes)

Transform3D represents a 3D transformation (position + rotation + scale) using Three.js internals. It is immutable by convention - every method returns a new instance.

tsx
import { Transform3D, Vector3 } from "remotion-bits";
Creating Transforms
tsx
const base = Transform3D.identity(); // Origin: position(0,0,0), rotation(0,0,0), scale(1,1,1)
Chaining Transforms

Every method returns a new Transform3D. Chain freely:

tsx
const cardPosition = base
  .translate(vmin * 50, vmin * -20, 0)  // Move right and up
  .rotateY(-15)                          // Rotate around Y axis (degrees)
  .scaleBy(1.5);                         // Scale uniformly by 1.5x
Show full SKILL.md (554 more words)Show less
Available Methods
tsx
// Position
transform.translate(x, y, z)           // Add to position
transform.translate(vector3)            // Add Vector3 to position

// Rotation (angles in DEGREES)
transform.rotateX(degrees)              // Rotate around X axis
transform.rotateY(degrees)              // Rotate around Y axis
transform.rotateZ(degrees)              // Rotate around Z axis
transform.rotateAround(origin, axis, degrees) // Rotate around arbitrary point+axis

// Scale
transform.scaleBy(uniform)             // Scale all axes equally
transform.scaleBy(sx, sy, sz)          // Scale per-axis

// Composition
transform.multiply(other)              // Matrix multiplication
transform.inverse()                    // Invert transform
transform.lerp(target, alpha)          // Linear interpolation (0-1)
transform.clone()                      // Deep copy

// Randomization (deterministic via seed)
transform.randomTranslate([minX, maxX], [minY, maxY], [minZ, maxZ], seed)
transform.randomRotateX([minDeg, maxDeg], seed)
transform.randomRotateY([minDeg, maxDeg], seed)
transform.randomRotateZ([minDeg, maxDeg], seed)

// Conversion
transform.toProps()                    // → { x, y, z, rotateX, rotateY, rotateZ, scaleX, scaleY, scaleZ, rotateOrder }
transform.toCSSMatrix3D()              // → "matrix3d(...)" CSS string
transform.toMatrix4()                  // → Three.js Matrix4
Using Transform3D with Step/Element3D

The .toProps() method converts a Transform3D to props that Step and Element3D accept:

tsx
const position = base.translate(vmin * 50, 0, 0).rotateY(-15);

// Spread directly into Step or Element3D
<Step id="my-step" {...position.toProps()} />

This is equivalent to manually specifying x={...} y={...} z={...} rotateX={...} rotateY={...} rotateZ={...}.

Using Transform3D as Keyframes

Pass Transform3D[] arrays as the transform property for smooth 3D interpolation between positions:

tsx
const start = base.translate(0, vmin * 20, 0);
const end = base.translate(0, 0, 0);

<Element3D
  centered
  transition={{
    duration: 35,
    transform: [start, end],  // Interpolates position, rotation, scale via slerp
    opacity: [0, 1],
    easing: "easeInOutCubic",
  }}
>
  <div>Animates from start to end</div>
</Element3D>

Transform keyframes use quaternion slerp for rotation (no gimbal lock) and linear interpolation for position and scale.

Vector3

Three.js Vector3 is re-exported for position math:

tsx
const offset = new Vector3(0, -vmin * 2, 0);
const farOffset = offset.clone().multiplyScalar(4.0); // Scale the offset
const combined = offset.clone().add(new Vector3(vmin * 5, 0, 0));

Scene3D System (3D Presentations)

Scene3D creates camera-based 3D presentations (like impress.js). The camera flies between Steps; content is placed in 3D space.

Architecture
Scene3D (perspective, timing)
├── Step (camera target 1) - children visible during this step
├── Step (camera target 2) - children visible during this step
├── ...
├── StepResponsive - element that animates differently per step
├── StepResponsive - another step-aware element
└── (any other children - always rendered)
Scene3D Container
tsx
<Scene3D
  perspective={1000}            // CSS perspective in px (depth effect)
  stepDuration={60}             // Default frames per step
  transitionDuration={60}       // Frames for camera transitions between steps
  easing="easeInOutCubic"       // Camera transition easing
>
  {/* Steps and content */}
</Scene3D>
Steps (Camera Targets)

Steps define where the camera flies to. They execute sequentially. Content inside a Step is visible when that step is active.

tsx
<Step
  id="intro"                   // Unique identifier (used by StepResponsive)
  {...position.toProps()}       // Camera target position/rotation/scale
  duration={120}               // Override stepDuration for this step (optional)
  transition={{                // Animate children on step ENTRY (optional)
    opacity: [0, 1],
    blur: [10, 0],
    duration: 20,
  }}
  exitTransition={{            // Animate children on step EXIT (optional)
    opacity: [1, 0],
    blur: [0, 10],
  }}
>
  {/* Content shown during this step */}
  <FloatingCard>...</FloatingCard>
</Step>

Step timing model:

  • Steps play sequentially: step1 → transition → step2 → transition → step3
  • stepDuration (on Scene3D): default duration each step is active
  • duration (on Step): override for specific step
  • transitionDuration (on Scene3D): how long the camera takes to move between steps
  • Total composition should be ≥ sum of all step durations
Element3D (3D Positioned Content)

Places content at a specific 3D position, independent of camera:

tsx
<Element3D
  centered                     // Center-align the element (transform-origin: center)
  x={vmin * 50} y={0} z={0}   // Position in 3D space
  style={{ width: vmin * 60 }}
  transition={{                // Animate on mount (optional)
    delay: 20,
    opacity: [0, 1],
    duration: 35,
    transform: [startTransform, endTransform], // 3D keyframes
    easing: "easeInOutCubic",
  }}
>
  <div>Content positioned in 3D space</div>
</Element3D>
StepResponsive (Step-Aware Animations)

The key to complex scenes. Elements define how they should look/position at each step, and animate between states when the camera moves:

tsx
<StepResponsive
  centered                     // Center the child
  style={{ position: 'absolute', fontSize }}
  steps={{
    // Key = step ID, Value = properties at that step
    'intro': {
      transform: [base, shiftedPosition],  // Transform3D keyframes
      opacity: [0, 1],
    },
    'elements': {
      transform: [elementPosition],        // Hold at this position
    },
    'outro': {
      transform: [outroStart, outroEnd],
      opacity: [1, 1, 1, 0],              // Hold visible, then fade
      duration: "step",                    // Match step duration
      easing: "easeInOutCubic",
    },
  }}
>
  <h1>Title That Follows Camera</h1>
</StepResponsive>

StepResponsive key behaviors:

  • Properties accumulate/inherit: if step "elements" doesn't set opacity, it keeps the value from the last step that set it
  • Arrays flatten to their final value when moving to the next step (no re-animation of past keyframes)
  • transform accepts Transform3D[] arrays - the primary way to position elements in 3D
  • duration: "step" makes the animation last the entire step duration
  • You can map the same props to multiple step IDs to hold position across steps

Mapping same props to multiple steps (common pattern):

tsx
const mapToAllElementSteps = (props) => ({
  'elements': props,
  'element-particles': props,
  'element-text': props,
  'element-code': props,
});

<StepResponsive
  steps={{
    'intro': { transform: [introPosition] },
    ...mapToAllElementSteps({ transform: [elementPosition] }),
    'outro': { transform: [outroPosition] },
  }}
>
  <h1>Elements</h1>
</StepResponsive>

Building Complex Scenes (Architecture Guide)

This is the recommended approach for any non-trivial composition. Scene3D provides camera management, step-based timing, 3D element positioning, and step-responsive animations - eliminating the need to manually manage useCurrentFrame(), <Sequence>, or CSS transforms.\n\n### Step 1: Plan the Scene Structure

Decide on the major sections (acts) and what the camera shows in each:

intro → elements → element-particles → element-text → ... → transitions → scenes → outro

Each section = one Step. Steps execute sequentially.

Step 2: Pre-compute All Positions

Use useMemo to build a position tree. This is THE critical architectural pattern:

tsx
const positions = useMemo(() => {
  const { vmin } = rect;
  const base = Transform3D.identity();

  // Define base positions for each scene section
  const elementsBase = base.translate(0, -vmin * 120, 0).rotateX(15);
  const transitionsBase = base.translate(vmin * 200, vmin * 50, 0).rotateY(-15);
  const scenesBase = base.translate(-vmin * 120, vmin * 70, 0).rotateY(15);

  // Derive sub-positions from bases
  const cardW = vmin * 70;
  const particlesCard = elementsBase.translate(-cardW, -vmin * 40, 0).rotateY(15);
  const textCard = elementsBase.translate(0, -vmin * 50, vmin * 10).rotateX(10);

  return {
    base,
    elements: {
      base: elementsBase,
      cards: { particles: particlesCard, text: textCard },
    },
    transitions: { base: transitionsBase },
    scenes: { base: scenesBase },
  };
}, [rect.width, rect.height]); // Re-compute on resize

Why pre-compute positions?

  • Separation of layout from rendering
  • Positions can be derived from each other (hierarchy)
  • Easy to adjust entire sections by changing the base
  • StepResponsive needs position references, not inline calculations
Step 3: Define Steps
tsx
<Scene3D perspective={1000} stepDuration={60} transitionDuration={60}>
  <Step id="intro" {...positions.base.toProps()} />
  <Step id="elements" {...positions.elements.base.toProps()} />
  <Step id="element-particles"
    {...positions.elements.cards.particles.toProps()}
    transition={{ opacity: [0, 1], blur: [10, 0] }}
  >
    <FloatingCard><ParticleDemo /></FloatingCard>
  </Step>
  <Step id="transitions" duration={120} {...positions.transitions.base.toProps()} />
  <Step id="scenes" duration={120} {...positions.scenes.base.toProps()} />
  <Step id="outro" {...positions.base.toProps()} duration={120} />
</Scene3D>
Step 4: Add Step-Responsive Elements

Titles, icons, and persistent elements that move with the camera:

tsx
<StepResponsive
  centered
  style={{ fontSize: vmin * 10, position: 'absolute' }}
  steps={{
    'intro': { transform: [positions.base, positions.base.translate(vmin * 7, 0, 0)] },
    'elements': { transform: [positions.elements.base.translate(vmin * 7, 0, 0)] },
    'outro': {
      transform: [positions.base.translate(vmin * 7, 0, 0), positions.base],
      duration: "step",
      easing: "easeInOutCubic",
    },
  }}
>
  <h1>Remotion Bits</h1>
</StepResponsive>
Step 5: Content Inside Steps

Steps can contain rich content - cards, particles, code blocks, counters:

tsx
<Step id="element-particles" {...cardPos.toProps()}
  transition={{ opacity: [0, 1], blur: [10, 0] }}>
  <FloatingCard>
    <Particles style={{ position: 'absolute', inset: 0, opacity: 0.6 }}>
      <Spawner rate={1} max={200} lifespan={80}
        velocity={{ x: 0, y: -0.6, varianceX: 0.4, varianceY: 0.2 }}
        area={{ width: rect.width, height: rect.height }}>
        <div style={{ width: vmin * 2, height: vmin * 2, borderRadius: '50%',
          background: 'var(--color-primary)' }} />
      </Spawner>
      <Behavior drag={0.96}
        wiggle={{ magnitude: 0.6, frequency: 0.25 }}
        opacity={[1, 0]}
        scale={{ start: 1, end: 0.4 }} />
    </Particles>
    <span style={{ position: 'relative', zIndex: 1, fontWeight: 'bold',
      fontSize: vmin * 3, fontFamily: 'monospace' }}>Particles</span>
  </FloatingCard>
</Step>

Components Quick Reference

AnimatedText
tsx
<AnimatedText
  style={{ fontSize: vmin * 5, fontWeight: 'bold' }}
  transition={{
    split: "character",           // "none" | "word" | "character" | "line" | custom separator
    splitStagger: 2,              // Frames between each unit
    opacity: [0, 1],
    y: [15, 0],
    blur: [2, 0],
    duration: 20,
    delay: 10,
    easing: "easeOutCubic",
    // Cycling text:
    cycle: { texts: ["Build", "Create", "Ship"], itemDuration: 40 },
    // Glitch effect:
    glitch: [0.6, 0],            // Glitch intensity AnimatedValue
  }}
>
  Hello World
</AnimatedText>
AnimatedCounter
tsx
<AnimatedCounter
  transition={{
    values: [0, 1000],            // Number keyframes
    color: ['#ff0000', '#00ff00'], // Color transition
    scale: [0.8, 1],
    duration: 30,
    delay: 10,
  }}
  prefix="$"
  postfix="+"
  toFixed={0}
  style={{ fontSize: vmin * 4, fontWeight: 'bold' }}
/>
TypeWriter
tsx
<TypeWriter
  text="import { TypeWriter } from 'remotion-bits';"
  typeSpeed={2}        // Frames per character
  deleteSpeed={1}
  pauseAfterType={60}  // Frames to wait before deleting
  delay={30}           // Start delay
  cursor="▋"
  style={{ fontSize: vmin * 2, fontFamily: 'monospace', whiteSpace: 'pre' }}
/>

// Multiple texts with cycling:
<TypeWriter
  text={["First line", "Second line", "Third line"]}
  deleteBeforeNext={true}
  loop={false}
  errorRate={0.05}     // 5% chance of typo
/>
CodeBlock
tsx
<CodeBlock
  code={`const x = useViewportRect();\nconsole.log(x.vmin);`}
  language="tsx"
  theme="dark"
  showLineNumbers={false}
  fontSize={vmin * 1.2}
  padding={vmin * 1.5}
  transition={{
    duration: 20,
    delay: 10,
    lineStagger: 2,                        // Frames between lines
    lineStaggerDirection: "forward",       // "forward" | "reverse" | "center" | "random"
    opacity: [0, 1],
    y: [8, 0],
    blur: [10, 0],
  }}
  highlight={[{ lines: [2, 3], color: "rgba(59,130,246,0.15)", opacity: [0, 1] }]}
  focus={{ lines: [2, 3], dimOpacity: 0.3, dimBlur: 2 }}
/>
StaggeredMotion
tsx
<StaggeredMotion
  transition={{
    opacity: [0, 1],
    scale: [0, 1],
    y: [20, 0],
    duration: 30,
    delay: 5,
    stagger: 3,                            // Frames between each child
    staggerDirection: "forward",           // "forward"|"reverse"|"center"|"random"
    easing: "easeOutCubic",
    borderRadius: 4,
  }}
>
  <div>Child 1</div>
  <div>Child 2</div>
  <div>Child 3</div>
</StaggeredMotion>
GradientTransition
tsx
<GradientTransition
  gradient={[
    "linear-gradient(0deg, #051226, #1e0541)",
    "linear-gradient(180deg, #a5d4dd, #5674b1)",
  ]}
  duration={90}
  easing="easeInOut"
  shortestAngle={true}   // Interpolate angles via shortest path
/>
MatrixRain
tsx
<MatrixRain fontSize={18} color="#00FF00" speed={1.2} density={0.8} streamLength={20} />
ScrollingColumns
tsx
<ScrollingColumns
  columns={[
    { images: ["/img1.jpg", "/img2.jpg"], speed: 100, direction: "up" },
    { images: ["/img3.jpg", "/img4.jpg"], speed: 150, direction: "down" },
  ]}
  height={rect.vmin * 40}
  gap={rect.vmin * 2}
/>
Particle System
tsx
<Particles style={{ position: 'absolute', inset: 0 }}>
  <Spawner
    rate={2}           // Particles per frame
    max={200}          // Maximum alive particles
    lifespan={100}     // Frames each particle lives
    burst={50}         // Emit 50 on first frame (optional)
    position={resolvePoint(rect, "center")}
    area={{ width: rect.width, height: 0 }}  // Spawn area
    velocity={{ x: 0, y: -2, varianceX: 1, varianceY: 0.5 }}
  >
    {/* Multiple children = random selection per particle */}
    <div style={{ width: vmin * 2, height: vmin * 2, borderRadius: '50%', background: '#fff' }} />
    <div style={{ width: vmin * 1, height: vmin * 1, borderRadius: '50%', background: '#aaa' }} />
  </Spawner>

  <Behavior
    gravity={{ y: 0.1 }}                              // Constant force
    drag={0.96}                                        // Air resistance (1=none, 0=instant stop)
    wiggle={{ magnitude: 0.6, frequency: 0.25 }}       // Random oscillation
    opacity={[1, 0]}                                   // Fade out over lifetime
    scale={{ start: 1, end: 0.3, startVariance: 0.2 }} // Shrink over lifetime
  />
</Particles>

Procedural Content Generation

For grids, backgrounds, and data-driven visuals, use deterministic random():

tsx
import { random } from 'remotion-bits';

const items = useMemo(() => {
  const palette = ['#fb4934', '#b8bb26', '#fabd2f', '#83a598'];
  const result = [];

  for (let r = 0; r < 10; r++) {
    for (let c = 0; c < 20; c++) {
      const seed = `grid-${r}-${c}`;
      const colorIndex = Math.floor(random(seed + 'color') * palette.length);
      const dist = Math.sqrt(r * r + c * c);

      result.push(
        <StaggeredMotion key={`${r}-${c}`}
          transition={{
            opacity: [0, 1],
            scale: [0, 1],
            delay: 30 + dist * 2,  // Wave from top-left
            duration: 40,
          }}>
          <div style={{
            width: vmin * 5, height: vmin * 5,
            background: palette[colorIndex],
          }} />
        </StaggeredMotion>
      );
    }
  }
  return result;
}, [vmin]);

random(seed) is deterministic - same seed always returns same value. Use unique string seeds per element.


Utility Functions

interpolate (non-monotonic)

Unlike Remotion's built-in, supports non-monotonic input ranges:

tsx
import { interpolate, Easing } from "remotion-bits";

// Hold then animate
interpolate(frame, [0, 30, 30, 60], [0, 0, 100, 100]);

// With easing
interpolate(frame, [0, 60], [0, 100], { easing: "easeOutCubic" });

// Clamp extrapolation
interpolate(frame, [0, 60], [0, 100], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' });
Color Interpolation
tsx
import { interpolateColorKeyframes } from "remotion-bits";

// Perceptually uniform (Oklch) color transitions
const color = interpolateColorKeyframes(["#ff0000", "#00ff00", "#0000ff"], progress);
Geometry
tsx
import { resolvePoint, createRect, Rect } from "remotion-bits";

const point = resolvePoint(rect, "center");       // { x: 960, y: 540 }
const point2 = resolvePoint(rect, { x: "50%", y: "25%" }); // { x: 960, y: 270 }

Bit Metadata Format

Bits export a metadata object and a Component:

tsx
export const metadata = {
  name: "MyBit",
  description: "Description of the bit.",
  tags: ["tag1", "tag2"],
  duration: 300,          // Total frames
  width: 1920,
  height: 1080,
  registry: {
    name: "bit-my-bit",
    title: "My Bit",
    description: "Registry description.",
    type: "bit" as const,
    add: "when-needed" as const,
    registryDependencies: ["animated-text", "scene-3d", "use-viewport-rect"],
    dependencies: [],
    files: [{ path: "path/to/MyBit.tsx" }],
  },
};

export const Component: React.FC = () => { /* ... */ };

Common Patterns

Floating Card Container
tsx
const FloatingCard = ({ children }) => (
  <div style={{
    position: 'relative',
    width: vmin * 60, height: vmin * 30,
    background: 'rgba(20, 20, 30, 0.6)',
    backdropFilter: 'blur(10px)',
    border: '1px solid rgba(255,255,255,0.2)',
    borderRadius: vmin * 1,
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    overflow: 'hidden',
    boxShadow: '0 0 20px rgba(0,0,0,0.2)',
  }}>
    {children}
  </div>
);
Scene with Entry Animations per Step
tsx
<Step id="particles-demo" {...cardPosition.toProps()}
  transition={{ opacity: [0, 1], blur: [10, 0] }}>
  <FloatingCard>
    {/* Content appears when camera arrives */}
  </FloatingCard>
</Step>
Step-Responsive Title Tracking Camera
tsx
<StepResponsive
  centered
  style={{ fontSize: vmin * 10, position: 'absolute', width: 'max-content' }}
  steps={{
    'intro': { transform: [startPos] },
    'main': { transform: [mainPos] },
    'outro': { transform: [mainPos, endPos], duration: "step", easing: "easeInOutCubic" },
  }}
>
  <h1>Section Title</h1>
</StepResponsive>
Animated Grid with Wave Timing
tsx
const dist = Math.sqrt(Math.pow(r - centerRow, 2) + Math.pow(c - centerCol, 2));
const delay = 30 + dist * 2; // Ripple outward from center

<StaggeredMotion transition={{ opacity: [0, 1], scale: [0, 1], delay, duration: 40 }}>
  <div style={{ width: size, height: size, background: color }} />
</StaggeredMotion>
Exit Transitions on Steps
tsx
<Step id="transitions" duration={120} {...pos.toProps()}
  exitTransition={{ blur: [0, 10], opacity: [1, 0] }}>
  {/* Content blurs out when camera leaves */}
</Step>
Element3D with Transform Keyframes
tsx
<Element3D centered
  style={{ width: vmin * 32, height: vmin * 24 }}
  transition={{
    delay: 10,
    opacity: [0, 1],
    duration: 35,
    transform: [
      base.translate(0, vmin * 20, 0),  // Start below
      base.translate(0, 0, 0),           // End at position
    ],
    easing: 'easeInOutCubic',
  }}>
  <div>slides up into place</div>
</Element3D>

Reference Documentation

For exhaustive API details:

© Marve10s, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 3 other files (references) in .agents/skills/remotion-bits of Marve10s/Better-Fullstack.

  • SKILL.md
  • references/components.md
  • references/patterns.md
  • references/utilities.md

Open the folder on GitHubat commit b03f092

Used in 1 other repository

We found 1 copy of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in Marve10s/Better-Fullstack, which our catalogue first saw on October 7, 2026.

Compare with similar skills

Remotion Bits next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Remotion Bits compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Remotion Bits this skillMarve10s/Better-Fullstack7521 repos~8.2kAutomated safety check: PassMIT
Remotion Best Practiceslyonjs/shortvid.io14733 repos~1kAutomated safety check: PassMIT
Remotion to HyperFrames Porterheygen-com/hyperframes59k3 repos~2.8kAutomated safety check: PassApache-2.0
Anything2explainerVincentwei1021/anything2explainer2.3k—~2.7kAutomated safety check: PassCustom licence
Remotion Motion Graphicshaidrrrry/claude-remotion-skill277—~2kAutomated safety check: PassMIT
Product DemoAlexwtlf/agentic-product-demo370—~8.8kAutomated safety check: PassCustom licence

Similar skills

  • Remotion Best Practices

    lyonjs/shortvid.io

    Best practices for Remotion - Video creation in React. An agent skill from lyonjs/shortvid.io.

    147 GitHub starsUsed in 33 repos~1k tokens
    Media & CreativeAuto-check passed
  • Remotion to HyperFrames Porter

    heygen-com/hyperframes

    Ports an existing Remotion (React) composition to HyperFrames HTML with GSAP, one way, and grades the result against a tiered set of reference fixtures.

    59k GitHub starsUsed in 3 repos~2.8k tokens
    Media & CreativeAuto-check passed
  • Anything2explainer

    Vincentwei1021/anything2explainer

    给一个主题,产出一条黑底 MG 风格(幕底可选星点或点阵波)、有配音字幕章节进度条的科普讲解视频(中文或英文;Remotion 代码动画;时长由用户定,常用 3–5 分钟)。内含可编译模板、图元库、配音/分镜/渲染工具、风格与动效规范、多 agent 分工协议与 QC 判据,以及一条完整样片(《RAG 与知识库》)作为质量标尺。Turn any topic into a narrated…

    2.3k GitHub stars~2.7k tokensUpdated 19 days ago
    Media & CreativeAuto-check passed
  • Remotion Motion Graphics

    haidrrrry/claude-remotion-skill

    Create and edit professional motion graphics videos with Remotion (React-based video).

    277 GitHub stars~2k tokensUpdated 1 mo ago
    Media & CreativeAuto-check passed
  • Product Demo

    Alexwtlf/agentic-product-demo

    Shoot, animate, title and optionally score product demo videos with Remotion — for a landing page, docs, onboarding, an app store listing or a social post.

    370 GitHub stars~8.8k tokensUpdated 1 mo ago
    Media & CreativeAuto-check passed
  • Remotion To Hyperframes

    chmonitor/chmonitor

    Port an existing Remotion (React) composition to HyperFrames HTML.

    299 GitHub starsUsed in 1 repo~2.5k tokens
    Media & CreativeAuto-check passed

More from Marve10s/Better-Fullstack

All 8 skills in this repo
  • Create Remotion Geist

    Marve10s/Better-Fullstack

    Create Remotion videos using the Geist design system aesthetic.

    752 GitHub stars~1.4k tokensUpdated today
    Auto-check passed
  • Better Fullstack

    Marve10s/Better-Fullstack

    Scaffold, plan, or extend Better Fullstack projects with the generator, CLI, or MCP server.

    752 GitHub stars~1.5k tokensUpdated today
    Auto-check passed
  • Modern Short Video

    Marve10s/Better-Fullstack

    Create modern product launch/pitch videos using Remotion. An agent skill from Marve10s/Better-Fullstack.

    752 GitHub stars~1.8k tokensUpdated today
    Auto-check: notes
  • Remotion Animation

    Marve10s/Better-Fullstack

    Generates animation configurations for Remotion including spring configs, interpolations, easing functions, and timing logic.

    752 GitHub stars~3.2k tokensUpdated today
    Auto-check passed
  • Add To Project

    Marve10s/Better-Fullstack

    Add capabilities, addons, deployment targets, generated CI, services, or stack updates to an existing Better Fullstack project.

    752 GitHub stars~507 tokensUpdated today
    Auto-check passed
  • Scaffold Project

    Marve10s/Better-Fullstack

    Scaffold a new app, API, backend, fullstack project, mobile app, polyglot service, monorepo, or starter with Better Fullstack.

    752 GitHub stars~716 tokensUpdated today
    Auto-check passed

Works with

Questions about Remotion Bits

What does Remotion Bits do?

Animation components and utilities for Remotion video projects. Remotion Bits is an agent skill from Marve10s/Better-Fullstack. Animation components and utilities for Remotion video projects.

When should I use Remotion Bits?

Remotion Bits fits situations like: building Remotion compositions with text animations; gradient transitions; particle effects; staggered motion effects.

How do I install Remotion Bits in Claude Code?

Run `npx skills add Marve10s/Better-Fullstack --skill remotion-bits -a claude-code`. Or copy the skill folder (.agents/skills/remotion-bits in Marve10s/Better-Fullstack) into .claude/skills/remotion-bits in your project. Claude Code loads it when a task matches its description.

How do I install Remotion Bits in Codex?

Run `npx skills add Marve10s/Better-Fullstack --skill remotion-bits -a codex`. Or copy the skill folder (.agents/skills/remotion-bits in Marve10s/Better-Fullstack) into .agents/skills/remotion-bits in your project. Codex loads it when a task matches its description.

Can I use Remotion Bits in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Marve10s/Better-Fullstack --skill remotion-bits -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/remotion-bits, .gemini/skills/remotion-bits, .github/skills/remotion-bits and .opencode/skills/remotion-bits in your project.

What does Remotion Bits need to run?

Going by SKILL.md and its folder, Remotion Bits needs the command-line tools its instructions call (npx and npm). Our summary lists: Node.js.

Does Remotion Bits access the network?

SKILL.md names 1 domain. In commands or code: unpkg.com; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.

Is Remotion Bits safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Remotion Bits use?

Remotion Bits is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Remotion Bits use?

About 8.2k tokens (SKILL.md is roughly 33k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 12k tokens, read only when the agent opens those files.

What are the alternatives to Remotion Bits?

Skills that share tags, products or a category with Remotion Bits: Remotion Best Practices (lyonjs/shortvid.io, 147 stars), Remotion to HyperFrames Porter (heygen-com/hyperframes, 59k stars), Anything2explainer (Vincentwei1021/anything2explainer, 2.3k stars) and Remotion Motion Graphics (haidrrrry/claude-remotion-skill, 277 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Remotion Bits?

Marve10s (a GitHub user) maintains it in Marve10s/Better-Fullstack, which has 752 GitHub stars. The repository holds 8 skills in this directory. The repository was last updated on October 7, 2026.

Source: Marve10s/Better-Fullstack on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.