Lottie: How to send animation to production without pain and loss of quality
Main chat
A chat for vibe coders: news, guides, live cases, marketplace, and finding executors.
What is dotLottie and why is it standard
In 2026, there are two formats: the old .json and the new .lottie (dotLottie). If you’re still working with .json, it’s time to switch.
.lottie is a ZIP archive that packs animations, assets and metadata into a single file. Compared to .json:
- Size 50-80% smaller
- Support for multiple animations in one file
- Built-in themes and slots for dynamic color swapping
- State Machines for Interactivity (similar to Rive, but simpler)
- One file runs on the web, iOS and Android without conversion
The old @lottiefiles/react-lottie-player is *deprecated and is no longer being updated. The new official package is @lottiefiles/dotlottie-react. It reads both .json and .lottie.
Part 1: What should a designer do before exporting
Most of the problems with Lottie in production are laid down during the animation stage in After Effects. Not for export, not for integration, but for export.
Call the layers clear
Lottie exports the layer structure directly to JSON. Layers named “Layer 1,” “Shape 47,” and “Comp 3” become unreadable JSON. The developer cannot find the desired element, color editing software is impossible.
Rule: Each semantic element is a separate named layer. "astronaut-body," "left-planet," "background-gradient" -- not "Shape 12.".
Avoid unsupported effects
Lottie doesn’t support everything After Effects does. Problematic techniques:
Not working or not working well: 3D layers, Gaussian Blur blur as a standalone effect, some blending modes, expressions with external dependencies, third-party plugins.
Working: Shape Layers, Masks, Track Mattes, most standard effects AE, Trim Paths, Repeater, Gradient Fill.
Before the final export, run Lottie Feature Checker right in the LottieFiles for After Effects plugin. It will show what is not supported on every platform.
Optimal settings
- FPS: 30 frames/sec for most UI animations. 24 for cinematics. 60 only if the animation is fluid and the file is small.
- **Size of composition: * Same size as the final screen size or slightly larger. Lottie is scalable, but exporting 1000×1000 if you need 200×200 is overweight.
- **Duration: * Just what you need. Extra seconds of emptiness at the beginning and end are extra kilobytes.
Export through LottieFiles for After Effects, not Bodymovin
LottieFiles plugin is an updated Bodymovin with additional features: preview on different devices directly in AE, Feature Checker, export immediately to .lottie (dotLottie), download to the team’s workspace.
Bodymovin still operates, but only exports .json without optimization.
Part 2: File optimization
Even well-made animation after export can weigh too much. Three tools that solve this without losing quality.
LottieFiles Optimizer
Built into the LottieFiles platform – download the file, get an optimized version. Removes unnecessary data, rounds the coordinates to the desired accuracy, compresses. It usually gives 20-40% of .json without visual changes.
dotLottie conversion
If you are still working with .json, convert to .lottie. On the LottieFiles platform, it's one click. Savings of 50-80% without loss of quality – due to ZIP compression.
Lottie Compress (opensource)
CLI tool for batch optimization:
npx lottie-compress input.json -o output.json --quality 80
It is useful when you need to automate optimization in CI / CD.
Part 3: Integration into React
Installation
npm install @lottiefiles/dotlottie-react
Do not install @lottiefiles/react-lottie-player, it is no longer updated.
Basic use
import { DotLottieReact } from "@lottiefiles/dotlottie-react"
export function LoadingSpinner() {
return (
<DotLottieReact
src="/animations/spinner.lottie"
loop
autoplay
style={{ width: 80, height: 80 }}
/>
)
}
The component accepts .lottie and .json in src prop – both formats work without code changes.
Software management of reproduction
import { useRef } from "react"
import { DotLottieReact } from "@lottiefiles/dotlottie-react"
export function SuccessAnimation({ onComplete }) {
const lottieRef = useRef(null)
return (
<DotLottieReact
src="/animations/success.lottie"
autoplay={false} // не запускать автоматически
loop={false}
dotLottieRefCallback={(instance) => {
lottieRef.current = instance
}}
onComplete={onComplete} // колбэк по завершении
/>
)
}
// Запуск из родителя
function Form() {
const animRef = useRef(null)
async function handleSubmit() {
await submitForm()
animRef.current?.play()
}
}
Lazy loading
Animations should not block the first render of the page. Load the component lazily:
import { lazy, Suspense } from "react"
const DotLottieReact = lazy(() =>
import("@lottiefiles/dotlottie-react").then(m => ({
default: m.DotLottieReact
}))
)
export function HeroAnimation() {
return (
<Suspense fallback={<div style={{ width: 200, height: 200 }} />}>
<DotLottieReact
src="/animations/hero.lottie"
loop
autoplay
/>
</Suspense>
)
}
fallback with fixed dimensions – so that there is no layout shift when booting.
Three typical components for production
Loading, Success and Empty are the most common tasks. Design them as separate components at once:
// components/animations/index.jsx
import { DotLottieReact } from "@lottiefiles/dotlottie-react"
export function LoadingState({ size = 80 }) {
return (
<DotLottieReact
src="/animations/loading.lottie"
loop autoplay
style={{ width: size, height: size }}
/>
)
}
export function SuccessState({ size = 120, onComplete }) {
return (
<DotLottieReact
src="/animations/success.lottie"
loop={false} autoplay
style={{ width: size, height: size }}
onComplete={onComplete}
/>
)
}
export function EmptyState({ size = 160 }) {
return (
<DotLottieReact
src="/animations/empty.lottie"
loop autoplay
style={{ width: size, height: size }}
/>
)
}
Hendoff via LottieFiles + Figma Dev Mode
If the team works in Figma, the Lottie animation handoff goes through the LottieFiles for Figma and Dev Mode plugin – without separate files in Slack and folders in Dropbox.
** Designer:** LottieFiles for Figma plugin allows you to convert animated Figma components directly to Lottie without After Effects. Suitable for simple UI animations: icons with states, load indicators, simple transitions. For complex animations, you still need After Effects.
Developer: In Figma Dev Mode, a LottieFiles section appears next to the component. There is an embed code, a link to a CDN and a code to connect. Copy src and paste it into a component – no manual file downloads.
An example with a CDN link:
The link is directly from Figma Dev Mode.
<DotLottieReact
src="https://lottie.host/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/file.lottie""
loophole
autoplay
style={{width: 120, height: 120}}
/>
CDN LottieFiles provides caching and optimized delivery. For production projects, it is better to keep files at home anyway (/public/animations/) - less dependence on external service.
Part 4: Common Problems and Solutions
Animation renders differently from After Effects. The reason is almost always an unsupported AE effect. Run a Feature Checker, find the red points, double-check with the designer.
The file is too big. ** First convert to .lottie, then run through Optimizer. If you still have a lot, ask the designer to simplify the number of simultaneously animated properties.
Animation twitches or slows down. Check useSubFrames - by default true, animation is updated for each requestAnimationFrame. If it is superfluous (30fps animation, 60fps screen) - put useSubFrames={false}:
<DotLottieReact src="animation.lottie" useSubFrames={false} />
Layout shift when downloading. Always specify dimensions through style or CSS - otherwise the container will collapse to 0 while the file is loaded and jumps when it boots.
Prompts for agents
Create three basic Lottie components:
Install @lottiefiles/dotlottie-react (not react-lottie-player - it is blocked).
Create three components in /components/animations/
LoadingState – loop: true, autoplay: true, size by size prop (default 80)
SuccessState - loop: false, autoplay: true, onComplete colback, default size 120
- EmptyState - loop: true, autoplay: true, default size 160
Animation files in /public/animations/: loading.lottie, success.lottie, empty.lottie.
Each component must have clearly defined width/height to avoid layout shift.
Export named exports from index.jsx.
Add animated success after submitting the form:
In the form /components/ContactForm. jsx add:
After successful submission, show SuccessAnimation instead of form
- Animation: /public/animations/success.lottie, single, loop: false
After completion of the animation (onComplete) in 1 second reset
shape and show it again
Before the animation loads - show the skeleton of the same size (200x200)
- Use @lottiefiles/dotlottie-react
Designer's checklist before file transfer
Preparation in After Effects
● All layers are meaningfully named, no Layer 1, Shape 47
● No Merge Paths That Break JSON Structure
● No unsupported effects (checked by Feature Checker)
FPS = 30, composition size = total element size
● No extra seconds of emptiness at the beginning and end
Exports
LottieFiles for After Effects, not Bodymovin
Format: dotLottie (.lottie), not JSON
● Run through LottieFiles Optimizer
Transfer to the developer
File uploaded to LottieFiles shared workspace
Required dimensions and playback mode (loop/once)
● Checked in preview on mobile