lottie-react: Lottie animations as a component or as a hook
Lottie animations in React: one component for the easy path, the whole engine when you need control.
At a glance
- What is it?
- lottie-react is a React library for Lottie animations with two surfaces: a component that takes a JSON file and plays it, and a hook that hands you the animation instance so you can drive it yourself. The size budget in the manifest is the interesting part, because it says the library treats bundle weight as a design constraint rather than an afterthought.
- Who is it for?
- lottie-react suits a React application that plays Lottie files and wants a small dependency with a clear escape from the simple case, because the hook exposes the same engine the component uses. It is a poor fit if you need the After Effects authoring workflow, since the library plays exported JSON and does not create it, and a poor fit if you cannot accept a runtime dependency on lottie-web.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 45 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One library, two ways in
The description captures the whole design in one sentence: Lottie animations in React, one component for the easy path, the whole engine when you need control.
That phrasing is a promise about the shape of the API, and it is unusual to see it stated so plainly. Most React wrappers for Lottie offer a component with a long list of props, and if you need to do something the props do not cover you end up reaching for a ref and calling into the underlying player yourself, with no type safety and no documentation of what the ref is.
lottie-react offers two documented surfaces instead. The first is a component, for the case where you have a JSON file and want it on screen. The second is a hook, for the case where you need to control the animation, react to its state, or drive it from your own code.
The hook is not a lesser version of the component. The readme says it returns the instance, and then names the three things that means: values that re-render with the animation, commands like play and seek, and a subscription point.
That is the shape of an engine API rather than a wrapper. The values are the current frame, the current progress or the current time, and because they re-render, a component can show a scrubber that tracks the animation. The commands are the transport. The subscription point is for the cases where re-rendering is too expensive and you would rather be told when something happened.
The project is MIT licensed, published to npm as lottie-react, and the website carries the guides, live examples and the full API reference.
The component, and the one thing you have to size yourself
The simple path is one import and one element.
import { Lottie } from "lottie-react";
export function Hero() {
return <Lottie src="/hero.json" autoplay loop />;
}The src prop takes three things: a path, a URL, or the parsed animation object. That last one matters for applications that already have the JSON, because it avoids a fetch entirely.
The sizing behaviour is the detail to notice, and it is a sensible design rather than an omission. The readme says the animation fills its element, so you size the element and you are done. There is no width and no height prop to set, and no layout fighting to reconcile.
That is the right default for a component that is nearly always used in a hero section or a placeholder, and it is consistent with how the web platform behaves, since a canvas or SVG that fills the box it is placed in does not force the box to grow. The cost is that you have to give the element a size, which means the layout decision moves to you, and that is a fair trade for the component not guessing.
The autoplay and loop props are the two most common controls and they are passed straight through to the animation, so the vocabulary of Lottie itself is still the vocabulary here.
The hook, and the ref you have to remember
The hook is the same idea with the engine exposed.
import { useLottie } from "lottie-react";
export function Hero() {
const lottie = useLottie({ src: "/hero.json", autoplay: true, loop: true });
return <div ref={lottie.setDisplayRef} style={{ height: 300 }} />;
}The options object mirrors the component's props, which is the right choice, because a migration from the component to the hook should not be a rewrite of your configuration.
The part that will catch you out is the ref. You have to attach the display ref yourself, with the callback the hook returns, because the hook is not rendering anything. The element you attach it to is the element the animation fills, so the same sizing rule applies: give it a height, as the example does, and the animation fills it.
That is a small cost for a fair gain. In exchange for the explicit ref you get the instance, the instance gives you the commands and the values, and the values are the part that matters for the applications people actually build. A video-like component with a play button, a progress bar and a caption that changes with the animation needs the current time and the ability to seek, and a component with a props list would either grow a dozen props for that or push you into the ref anyway.
The subscription point completes the picture. When re-rendering on every frame is the wrong trade, you can subscribe instead, which is the escape hatch for a long animation in a list.
The size budget is the design constraint
The manifest carries a size-limit configuration, and it is unusual to see a published library state its bundle budget in a way that is enforced in the repository.
There are two entries. The component import is measured against the built entry point with a gzip limit of 5 kilobytes, and the hook import has a limit of 3.95 kilobytes. In both cases the measurement ignores React, React DOM and lottie-web, so the budget covers only this library's own code.
Two things follow from that. First, the component is allowed to cost about a kilobyte more than the hook, which matches the description: the easy path is a convenience and the engine path is the product. Second, the budgets are small enough that they are a design constraint rather than an aspiration. A wrapper that pulled in a rendering library of its own, or that bundled a copy of the animation player, would blow them immediately.
The readme says the same thing in prose: the package is tree-shakeable, and an import pays only for what it reaches. The manifest supports that, with the side effects flag set to false, which is the declaration a bundler uses to decide that importing the hook does not drag in the component and its dependencies.
For an evaluator, the budgets are a good proxy for how the project is maintained. A library that tracks its own size in the repository is a library whose author cared about the cost of using it, which is a reasonable expectation for a component that most applications will use once or twice on a page.
Packaging, peer dependencies and the lottie-web question
The packaging is modern and specific.
The package is an ES module with a CommonJS fallback, and the exports map gives each condition its own type declarations, with a separate declaration file for the require condition because the types differ between the two module systems. The main entry points at the CommonJS build, the module entry at the ES build, and the types entry at the declarations. Only the build directory is published.
The peer dependencies are React and React DOM at 18.2 or newer, and lottie-web comes with the package rather than being something you install yourself. That last point is worth a moment, because lottie-web is the actual animation player, the library that parses the JSON and drives the frames. Bundling it means one dependency instead of two and no version mismatch, and it is also the reason the size limits ignore it, since it is by far the largest part of the payload.
The website is at lottiereact.com, and the topics listed for the repository cover After Effects as the authoring tool, the lottie-web ecosystem, React hooks, and TypeScript, which is a fair summary of what the package is for.
Version 3, the migration guide and the maintenance pace
The readme has one line for people arriving from the previous major version, and it is a good sign.
Coming from v2? The migration guide maps every v2 surface onto v3. The promise that every surface is mapped is the strong version of that claim, and it tells you that version 3 is a rewrite rather than an increment. The package keywords still mention the player and the tree-shakeable bundle, and the description was clearly rewritten for the new API, with the component and the hook as the two named surfaces.
The release cadence matches a project in active development. Version 3.1.0 came out on 2026-08-16, 3.1.1 on 2026-08-27 and 3.1.2 on 2026-09-07, and the last push to the repository was the same day, with the repository not archived.
So the version number moves often and the major version is recent. That combination is what you would expect from a rewrite that has just settled, and it has a practical consequence: read the migration guide before you move a v2 application across, because the surface has clearly been reorganised rather than extended.
The repository supports the impression of a serious project. There is a Biome configuration for formatting and linting, a tsdown configuration for the build, a Vitest configuration for the tests, a pnpm workspace with a lock file, a patches directory, a website directory, a contributing guide, a security policy, an editor configuration, a Node version file, and separate agent instruction files.
The development engines are declared as well, with pnpm at a specific version and Node at a minimum, both with the failure mode set to warn rather than error, which is a friendly choice for contributors on a different machine and a slightly less safe one for a published package, since the declared minimum is what most people will read.
Editorial conclusion
lottie-react suits a React application that plays Lottie files and wants a small dependency with a clear escape from the simple case, because the hook exposes the same engine the component uses. It is a poor fit if you need the After Effects authoring workflow, since the library plays exported JSON and does not create it, and a poor fit if you cannot accept a runtime dependency on lottie-web. Before you adopt it, read the v2 to v3 migration guide, because a major version that maps every surface suggests real churn, and check the size limit configuration, since that tells you what the maintainers consider an acceptable cost for the simple path.
Frequently asked questions
How do I install lottie-react?
With npm i lottie-react. React and React DOM at 18.2 or newer are peer dependencies, and the lottie-web player comes with the package, so there is no second installation step.
What is the difference between the Lottie component and the useLottie hook?
The component renders the animation and takes a path, a URL or a parsed animation object as its source, filling the element it is placed in. The hook takes the same options and returns the instance, giving you values that re-render with the animation, commands such as play and seek, and a subscription point.
How large is lottie-react?
The manifest declares size limits that are enforced in the repository: 5 KB gzipped for the component import and 3.95 KB for the hook import, measured without React, React DOM and lottie-web. The package is also marked as having no side effects, so an import pays only for what it reaches.
How do I move an application from lottie-react v2 to v3?
The readme points to a migration guide that maps every v2 surface onto v3, and the project publishes a separate full API reference with guides and live examples on its website. Version 3 is a reorganised API rather than an increment, so the guide is the thing to read before changing code.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/gamote-lottie-react)Was this useful?