RVE LogoReact Video EditorDOCS
RVE SDK/Quick Start/Setup Lottie

Setup Lottie

Add Lottie animations to your video editor — built-in templates, user uploads, and custom libraries via an adaptor

RVE has a built-in Lottie panel. The panel has two tabs:

  • Library: End users browse Lottie templates.
  • Upload: End users drop in their own .json files or paste a URL.

After a user adds a Lottie item, the user can loop it, change its speed, move it, add enter and exit animations, and add keyframes.

The panel works with no configuration and shows a small curated library. To serve your own templates, write a Lottie adaptor and pass it in the adaptors prop.

How it works

Editor UI
├── Library tab: getTemplates() of each adaptor, then one grid of previews
├── Upload tab: validate .json (Bodymovin shape + size cap), then add to timeline
└── Item selected: Style tab (opacity, position) and Animate tab (loop, speed, animations, keyframes)

Player + Renderer
└── lottie-layer-content loads @remotion/lottie with a dynamic import

The built-in adaptor has a small library of curated .json files. To show other templates, pass your own adaptors. This is the same pattern as images and video.

Step 1: Install @remotion/lottie

npm install @remotion/lottie@4.0.481

Version matching

@remotion/lottie must use the exact same version as every other @remotion/* package in your project. If the versions are different, the renderer throws an error at runtime.

Step 2: Use the defaults

If you do not set adaptors.lottie, the editor uses the built-in curated library and the Upload tab.

<ReactVideoEditor projectId="my-project" />

The panel appears in the sidebar with the Lottie icon. Open it and click a tile. The editor adds the animation to a new track at the current frame.

Step 3: Serve your own templates (optional)

To show your own library, write a Lottie adaptor. For example, you can serve animations from your CMS, a LottieFiles account, or a private bucket.

The LottieAdaptor and LottieTemplate types are not exported from /types. Get them from the exported Adaptors type instead:

lib/my-lottie-adaptor.ts
import type { Adaptors } from '@reactvideoeditor/react-video-editor/types';

type LottieAdaptor = NonNullable<Adaptors['lottie']>[number];
type LottieTemplate = Awaited<ReturnType<LottieAdaptor['getTemplates']>>['items'][number];

export const myLottieAdaptor: LottieAdaptor = {
  name: 'my-library',
  displayName: 'My Library',
  description: 'Brand-approved Lottie animations',

  async getTemplates() {
    const res = await fetch('/api/lottie/list');
    const items = (await res.json()) as LottieTemplate[];
    return { items };
  },
};

Then pass it in the adaptors prop:

import { ReactVideoEditor } from '@reactvideoeditor/react-video-editor/react-video-editor';
import { myLottieAdaptor } from '@/lib/my-lottie-adaptor';

<ReactVideoEditor
  projectId="my-project"
  adaptors={{
    lottie: [myLottieAdaptor],
  }}
/>;

Your adaptors replace the built-in library

If you set adaptors.lottie, your array replaces the built-in curated library. The built-in adaptor is not exported, so you cannot add it back. The Upload tab stays available.

The adaptor shape

// Shape of the Lottie adaptor. These types are not exported, so copy them
// or get them from Adaptors['lottie'] as shown above.
interface LottieAdaptor {
  name: string;          // Stable identifier, used as a key
  displayName: string;   // Shown to end users
  description?: string;  // Optional secondary text
  getTemplates(): Promise<{ items: LottieTemplate[] }>;

  /** Optional remote search. The editor does not call it yet. */
  search?(query: string): Promise<{ items: LottieTemplate[] }>;
}

interface LottieTemplate {
  id: string;              // Unique within the adaptor
  title: string;           // Display label
  src: string;             // Public URL to the .json file
  width: number;           // Native composition width (px)
  height: number;          // Native composition height (px)
  durationInFrames: number; // In the editor's FPS, not the file's native rate
}

Calculate `durationInFrames`

Lottie files store an op (out point), ip (in point), and fr (native frame rate). Use this formula to convert to the editor's FPS:

const durationInFrames = Math.max(
  1,
  Math.round(((json.op - json.ip) * EDITOR_FPS) / json.fr),
);

Multiple adaptors

You can pass more than one Lottie adaptor. The Library tab merges the templates of all adaptors into one grid.

<ReactVideoEditor
  projectId="my-project"
  adaptors={{
    lottie: [
      myBrandLibraryAdaptor,
      mySeasonalCampaignAdaptor,
      myInternalCDNAdaptor,
    ],
  }}
/>

End-user uploads

The Upload tab is always available to end users. It accepts:

  • .json files only
  • Files up to 5 MB
  • Bodymovin-shaped JSON (the editor validates it in the browser)
  • URLs pasted into the URL field (the editor fetches and validates them)

If the file contains expressions, the user sees a warning. The renderer does not support expressions, so the animation can flicker in the exported video.

What end users can configure per item

When a user selects a Lottie item, the item panel shows two tabs:

  • Style
    • Opacity
    • Position: X, Y, width, and height
  • Animate
    • Playback: Loop repeats the animation for the full item duration (default on). Speed goes from 0.5 to 2 (default 1).
    • Animations: Enter and exit animations, with the same controls as text, images, and videos.
    • Keyframes: Lottie items support keyframes, for example on position, size, and opacity.

featureOverrides cannot hide these controls. See feature overrides for the actions that you can lock or track.

Custom render compositions

If you build your own render composition, render Lottie items with LottieLayerContent inside LayerBox. If you do not use LayerBox, keyframes do not move the item. See custom compositions.