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 componentThe 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.465Remotion 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:
.jsonfiles 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)
- Speed —
0.5–2(default1) - 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.