@json-render/remotion

Remotion video renderer. Turn JSON timeline specs into video compositions.

schema

The timeline schema for video specs. Use with defineCatalog from core.

import { defineCatalog } from '@json-render/core';
import { schema, standardComponentDefinitions } from '@json-render/remotion';

const catalog = defineCatalog(schema, {
  components: standardComponentDefinitions,
  transitions: standardTransitionDefinitions,
  effects: standardEffectDefinitions,
});

Renderer

The main composition component that renders timeline specs. Use with Remotion's Player or in a Remotion project.

import { Player } from '@remotion/player';
import { Renderer } from '@json-render/remotion';

function VideoPlayer({ spec }) {
  return (
    <Player
      component={Renderer}
      inputProps={{ spec }}
      durationInFrames={spec.composition.durationInFrames}
      fps={spec.composition.fps}
      compositionWidth={spec.composition.width}
      compositionHeight={spec.composition.height}
      controls
    />
  );
}

Custom Components

Pass custom components to the Renderer:

import { Renderer, standardComponents } from '@json-render/remotion';

const customComponents = {
  ...standardComponents,
  MyCustomClip: ({ clip }) => <div>{clip.props.text}</div>,
};

<Player
  component={Renderer}
  inputProps={{ spec, components: customComponents }}
  // ...
/>

Standard Components

Pre-built video components included in the package:

import {
  TitleCard,      // Full-screen title with subtitle
  ImageSlide,     // Full-screen image display
  SplitScreen,    // Two-column layout
  QuoteCard,      // Quote with attribution
  StatCard,       // Large statistic display
  LowerThird,     // Name/title overlay
  TextOverlay,    // Centered text overlay
  TypingText,     // Terminal typing animation
  LogoBug,        // Corner logo watermark
  VideoClip,      // Video playback
} from '@json-render/remotion';

TitleCard Props

{
  title: string;
  subtitle?: string;
  backgroundColor?: string;  // default: "#1a1a1a"
  textColor?: string;        // default: "#ffffff"
}

TypingText Props

{
  text: string;
  charsPerSecond?: number;   // default: 15
  showCursor?: boolean;      // default: true
  cursorChar?: string;       // default: "|"
  fontFamily?: string;       // default: "monospace"
  fontSize?: number;         // default: 48
  textColor?: string;        // default: "#00ff00"
  backgroundColor?: string;  // default: "#1e1e1e"
}

Catalog Definitions

Pre-built definitions for creating catalogs:

import {
  standardComponentDefinitions,   // All standard component definitions
  standardTransitionDefinitions,  // fade, slideLeft, slideRight, etc.
  standardEffectDefinitions,      // kenBurns, pulseGlow, colorShift
} from '@json-render/remotion';

// Use in your catalog
const catalog = defineCatalog(schema, {
  components: {
    ...standardComponentDefinitions,
    // Add custom components
  },
  transitions: standardTransitionDefinitions,
  effects: standardEffectDefinitions,
});

Hooks & Utilities

useTransition

Calculate transition styles for a clip based on current frame:

import { useTransition } from '@json-render/remotion';
import { useCurrentFrame } from 'remotion';

function MyComponent({ clip }) {
  const frame = useCurrentFrame();
  const transition = useTransition(clip, frame);
  
  return (
    <div style={{
      opacity: transition.opacity,
      transform: transition.transform,
    }}>
      Content
    </div>
  );
}

ClipWrapper

Automatically apply transitions to clip content:

import { ClipWrapper } from '@json-render/remotion';

function MyClip({ clip }) {
  return (
    <ClipWrapper clip={clip}>
      <div>My content with automatic transitions</div>
    </ClipWrapper>
  );
}

Types

TimelineSpec

interface TimelineSpec {
  composition: {
    id: string;
    fps: number;
    width: number;
    height: number;
    durationInFrames: number;
  };
  tracks: Track[];
  clips: Clip[];
  audio: {
    tracks: AudioTrack[];
  };
}

Clip

interface Clip {
  id: string;
  trackId: string;
  component: string;
  props: Record<string, unknown>;
  from: number;
  durationInFrames: number;
  transitionIn?: {
    type: string;
    durationInFrames: number;
  };
  transitionOut?: {
    type: string;
    durationInFrames: number;
  };
}

TransitionStyles

interface TransitionStyles {
  opacity: number;
  transform: string;
}

ComponentRegistry

type ClipComponent = React.ComponentType<{ clip: Clip }>;
type ComponentRegistry = Record<string, ClipComponent>;

Transitions

Available transition types:

  • fade - Opacity fade in/out
  • slideLeft - Slide from right
  • slideRight - Slide from left
  • slideUp - Slide from bottom
  • slideDown - Slide from top
  • zoom - Scale zoom in/out
  • wipe - Horizontal wipe