What a Lottie file actually is
A Lottie file is JSON. Open one in a text editor and you will find a list of layers, each with a set of animated properties, each property a list of keyframes with values and bezier handles. There are no pixels in it unless an image was imported, in which case that image sits inside the JSON as a base64 string and the file size jumps accordingly.
It is produced by exporting from After Effects with the Bodymovin plugin, or from Glaxnimate, Haiku, or any of several open-source writers. It is played back by a runtime: lottie-web in a browser, lottie-ios, lottie-android, and ports for Flutter, React Native and others. The runtime reads the keyframes and redraws the shapes every frame.
That is the whole idea, and it explains both its strengths and every one of its failures. The strengths: a 40KB file that renders crisply at any size, on any platform, with the same timing, and that a designer can replace without a developer. The failures: anything that is not expressible as “shapes with animated properties” does not survive the export.
What does not export
This is the list that costs people a day each time they rediscover it.
- Effects. Almost all of them. Glow, drop shadow as an effect, blur, distortions, generate effects: gone, or approximated badly. Build glow with actual shapes and opacity.
- Expressions. Newer runtimes support a limited subset, but an expression-driven rig is not portable. Bodymovin can bake expressions into keyframes on export, which works and produces a much larger file.
- Merge paths. Supported in some renderers and not others, which is worse than unsupported because it works on your machine.
- Layer styles, 3D layers with real depth, cameras, motion blur, time remapping, adjustment layers, track mattes beyond the simple cases.
- Auto-orient, parenting past certain depths, and most expression controls.
The rule the export gives you: shape layers, solids, precomps, masks, simple track mattes, and transform properties. Build inside that box and the file behaves everywhere.
The two renderers
lottie-web can draw with SVG, canvas, or HTML. The choice matters more than most people realise.
SVG renderer (the default) creates a DOM element for every shape, group and mask. Crisp at any scale, correct anti-aliasing, works with CSS. It also means a file with 400 shapes creates roughly 400 nodes that are re-laid-out every frame. Past a few hundred, this becomes visible main-thread work, and on a low-end phone it stutters.
Canvas renderer draws to a single element. Far faster on complex files. You lose per-shape CSS control and you have to redraw on resize to keep it sharp, because the canvas is a fixed pixel buffer.
The practical test: render your file, open the DevTools performance panel, and look at the main thread during playback. If you see a solid block of scripting work at 16ms intervals, switch renderer.
The sizes and the traps
A typical illustrated Lottie is 15 to 60KB. Two things blow that up:
Imported raster images. They are base64-encoded into the JSON, which adds about 33 per cent to their size on top of losing all compression benefits. A Lottie with a photograph in it is not a vector file with a small extra; it is a badly packed image file with some vectors attached. Keep images external where the runtime supports it, or do not use them.
Baked expressions and very dense keyframes. An expression sampled per frame for ten seconds at 60fps is 600 keyframes on that property. Reduce the frame rate of the export (24 or 30 is almost always enough) and the file halves.
dotLottie (.lottie) is a zip containing the JSON plus any assets. It is typically 50 to 80 per cent smaller than the raw JSON for image-bearing files and has a cleaner story for multiple animations in one bundle. Support is now good across the official runtimes.
Controlling it
This is where Lottie beats a video. The runtime exposes the timeline:
const anim = lottie.loadAnimation({
container: el, renderer: 'svg', loop: false,
autoplay: false, path: '/motion/checkout.json'
});
anim.playSegments([0, 40], true); // the "loading" portion
anim.setSpeed(1.2);
anim.goToAndStop(38, true); // frame-accurate holdMarking sections of a single file and playing segments is how you build a state-driven animation without a separate file per state. Name your frame ranges in the handover, because a developer cannot find them by looking.
Honouring reduced motion
A looping Lottie is continuous motion and belongs inside the reduced-motion rules from the previous module. The runtime cannot know; you have to check the media query and either call goToAndStop on a representative frame or not load the animation at all. Shipping a static poster frame as an SVG for that case is a five-minute job that almost nobody does.
The free path
- Glaxnimate: open source, authors and exports Lottie directly, no After Effects required.
- python-lottie: a library that reads, writes and converts Lottie files, useful for batch edits and for stripping unsupported features.
- LottieFiles has a free tier with a preview and optimiser; the file format itself is open and none of the tooling is mandatory.
- Blender with grease pencil for authoring, exported through an SVG sequence, is a viable if awkward free route for frame-by-frame vector work.
The limitation
Lottie’s compatibility story is not one thing. The web, iOS and Android runtimes have historically differed in exactly which features they implement, and a file that looks right in one can be subtly wrong in another: a mask that clips differently, a trim path that runs backwards, a gradient that bands. There is no conformance suite that settles it.
So the only safe process is to preview the exported file on every target platform before sign-off, not in the design tool. The design tool is not the renderer, and the difference between them is where the day goes.
Every lesson here is open. Your progress is recorded once you pass the Video with AI exam.
Check your understanding
A Lottie file is 1.4MB and stutters on a mid-range phone. The designer insists the composition is simple. What are the two most likely causes, given how the format works?
Pick the one you would defend. Your answer stays private.
Stuck on something?Ask Deepa, your AI tutor
