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 ships with a built-in Lottie panel. End users get a Library tab for browsing templates and an Upload tab for dragging in their own .json files or pasting a URL. Selected items can be looped, sped up or slowed down, positioned, and given enter/exit animations like any other media type.

The panel works out of the box with a small curated library. To serve your own templates, implement a LottieAdaptor and pass it through the adaptors prop.

Why is @remotion/lottie a peer dep?

@remotion/lottie is declared as an optional peer dependency. The Lottie layer dynamically imports it at runtime — if you don't install it, the panel UI still appears, but Lottie items won't render in the player or in your exported videos. Install it whenever you want the Lottie feature.

How it works

Editor UI
├── Library tab  →  adaptor.getTemplates()  →  grid of previews
├── Upload tab   →  validate .json (Bodymovin shape + size cap) → add to timeline
└── Item selected →  Settings / Style panels (loop, speed, position, animation, opacity)

Player + Renderer
└── lottie-layer-content  →  dynamic import('@remotion/lottie')  →  Lottie component

The built-in adaptor ships a small library of curated .json files. Anything beyond that comes from adaptors you pass in — same pattern as images, video, or stickers.

Step 1: Install @remotion/lottie

npm install @remotion/lottie@4.0.465

Remotion version matching

@remotion/lottie must use the exact same version as every other @remotion/* package in your project. Remotion enforces this at runtime and will throw on a mismatch.

Step 2: That's it for the defaults

The default lottie adaptors are wired automatically. When you pass no lottie key in your adaptors prop, RVE renders 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, click a tile, and the animation is added to a new track at the current frame.

Step 3: Serve your own templates (optional)

To expose a curated library — e.g. animations stored in your CMS, a LottieFiles account, or a private bucket — implement a LottieAdaptor.

import type {
  LottieAdaptor,
  LottieTemplate,
} from '@reactvideoeditor/react-video-editor/types';

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 through the adaptors prop:

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

<ReactVideoEditor
  adaptors={{
    lottie: [myLottieAdaptor],
  }}
/>;

Your adaptor's tiles render alongside the built-in library in the Library tab. The Upload tab remains available regardless.

The LottieAdaptor interface

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 hook. Not wired in v1. */
  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
}

Computing `durationInFrames`

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

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

Multiple adaptors

You can pass multiple Lottie adaptors. Each one shows up as a separate tab inside the Library panel.

<ReactVideoEditor
  adaptors={{
    lottie: [
      myBrandLibraryAdaptor,
      mySeasonalCampaignAdaptor,
      myInternalCDNAdaptor,
    ],
  }}
/>

The built-in curated adaptor is included automatically — you don't need to re-add it unless you want to control its position relative to your own.

End-user uploads

The Upload tab is shown to end users by default. It accepts:

  • .json files only
  • Files up to 5 MB
  • Bodymovin-shaped JSON (validated client-side)
  • URLs pasted into the URL field (also fetched and validated)

If the uploaded file contains expressions, the user sees a warning — expressions aren't supported by @remotion/lottie at render time and may behave differently in the preview vs. the exported video.

What end users can configure per item

Once a Lottie item is on the timeline, the details panel exposes:

  • Loop — repeat for the item's full timeline duration (default on)
  • Speed0.52 (default 1)
  • Position — X / Y / width / height
  • Animation — enter and exit animations from the shared animation library (same controls as text / image / video)
  • Opacity — under the Style tab

These are all driven by the same prop shape as other media types, so any feature override that hides Settings or Style controls applies here too.