React

Use @editframe/react for TypeScript-typed compositions with React component syntax.

Install

bash
npm install @editframe/react

Components

All elements are available as React components:

ts
import { Configuration, Timegroup, Video, Audio, Image, Text, Captions, Surface, Waveform } from "@editframe/react";

Use camelCase for writable element properties and className for CSS classes. Timing attributes without a matching camelCase property keep their HTML names:

These are common mappings. See each element's reference for its full attribute and property list.

Configuration and Text accept ordinary JSX props, children, and element refs directly; no app-side retyping is needed. Wrappers forward element properties and attributes, while declared component events and refs have specific types.

The examples below show composition components. For export, give the root Timegroup the id supplied by a TimelineRoot; its clone factory remounts hooks and function props. See the complete React export example.

Basic example

jsx
import { Timegroup, Text } from "@editframe/react";

export default function Composition() {
  return (
    <Timegroup
      duration="5s"
      className="w-[1920px] h-[1080px] bg-black flex items-center justify-center"
    >
      <Text className="text-white text-8xl font-bold">Hello from React</Text>
    </Timegroup>
  );
}

Sequence with video and text

jsx
import { Timegroup, Video, Text } from "@editframe/react";

export default function Composition() {
  return (
    <Timegroup mode="sequence" className="w-[1920px] h-[1080px] bg-black">
      <Timegroup mode="fixed" duration="5s" className="absolute w-full h-full">
        <Video
          src="https://assets.editframe.com/bg.mp4"
          sourcein="2s"
          sourceout="7s"
          className="size-full"
          style={{ objectFit: "cover" }}
        />
        <Text className="absolute inset-0 flex items-center justify-center text-white text-7xl font-bold">
          Scene One
        </Text>
      </Timegroup>
      <Timegroup mode="fixed" duration="8s" className="absolute w-full h-full">
        <Video
          src="https://assets.editframe.com/bars-n-tone.mp4"
          className="size-full"
          style={{ objectFit: "cover" }}
        />
      </Timegroup>
    </Timegroup>
  );
}

useTimingInfo

useTimingInfo() returns the current playback time for a Timegroup. Use it for animations driven by the composition clock so seeking and export reproduce the same state.

jsx
import { Timegroup, Text, useTimingInfo } from "@editframe/react";

function AnimatedHeadline() {
  const { percentComplete, ref } = useTimingInfo();

  return (
    <Timegroup
      ref={ref}
      duration="3s"
      className="w-[1920px] h-[1080px] bg-black flex items-center justify-center"
    >
      <Text
        className="text-white text-8xl font-bold"
        style={{ opacity: percentComplete }}
      >
        Fades In
      </Text>
    </Timegroup>
  );
}

The hook creates a ref internally and returns it. Pass it to the <Timegroup> you want to observe:

The legacy ownCurrentTimeMs and durationMs fields remain available in milliseconds. New code should use the seconds fields.

Media speed and audio fades

Pass playbackRate as a number from 0.25 to 4; audio keeps its pitch in preview and export. volumeAtTime receives clip-local composition seconds and returns a multiplier applied to volume.

jsx
import { Timegroup, Audio } from "@editframe/react";

const fade = (localTime) => Math.min(localTime, 4 - localTime);

export default function Music() {
  return (
    <Timegroup duration="4s">
      <Audio
        src="https://assets.editframe.com/muted-guitar.mp3"
        sourcein="2s"
        sourceout="10s"
        playbackRate={2}
        volume={0.6}
        volumeAtTime={fade}
      />
    </Timegroup>
  );
}

This plays eight source seconds in four composition seconds, with one-second fades at both ends. Fade values are clamped to 0–1; nonfinite values use 1. Export evaluates fades for every output audio sample. Video supports the same props. See the time model for trim and duration rules.

Data-driven compositions

jsx
import { Timegroup, Text } from "@editframe/react";

const slides = [
  { text: "Slide One", bg: "bg-indigo-900" },
  { text: "Slide Two", bg: "bg-purple-900" },
  { text: "Slide Three", bg: "bg-rose-900" },
];

export default function Composition() {
  return (
    <Timegroup mode="sequence" className="w-[1920px] h-[1080px]">
      {slides.map((slide) => (
        <Timegroup
          key={slide.text}
          duration="3s"
          className={`w-full h-full flex items-center justify-center ${slide.bg}`}
        >
          <Text className="text-white text-7xl font-bold">{slide.text}</Text>
        </Timegroup>
      ))}
    </Timegroup>
  );
}
The browser entry point registers custom elements and requires a DOM. For server-rendered composition markup, use @editframe/react/server. Mount GUI controls and playback hooks on the client.