Install Motion Path — it’s free → See the product page
The short answer: Figma Motion has no Lottie export of its own. Install Motion Path, animate your layer, then open the … menu in the plugin titlebar and choose Copy as code → Lottie. You get a complete Lottie 5.9 document that you can copy to the clipboard or download as motion-path.json, ready for lottie-ios, lottie-android, lottie-react-native or lottie-web. The whole thing takes about fifteen seconds once the motion is applied.
The rest of this page is the detail behind those fifteen seconds: where the export sits, what actually lands in the file, why the position track has far more keyframes than you drew, what Lottie cannot carry from your animation, and how to check the result before you hand it to an engineer.
Figma’s native Motion panel is genuinely good at handing work over. Select an animated layer, open Copy as, and you can take CSS, React or JSON straight out of the file. Dev Mode inspects the keyframes. None of that is missing.
What is missing is the one format that mobile and web product teams have standardised on. Lottie is a vector animation document — a JSON file describing shapes and the keyframes that move them — and it is what an iOS, Android, React Native or web build actually consumes when a designer hands over motion. Figma’s Copy as does not produce it.
Motion Path fills that gap, and it fills it from inside the same panel you were already working in. Here is every route out of that panel, so you can see where Lottie sits among them:
Three of the six menu items are exports. Copy as code is the one that produces Lottie. Export video is covered in the video export guide, and Config JSON is a different thing entirely — if you arrived here because you searched for JSON, read which of the three JSONs you actually want before going further.
This is the step people skip, and it is the reason an export comes back empty. The plugin previews your motion live in the panel before anything is written to the canvas. That preview is not an animation yet. Press Apply motion path and the plugin writes real, native Figma Motion keyframe tracks — position, rotation, scale, opacity and path trim — onto your layer.

Everything downstream depends on this. The plugin does not run its own animation engine — it writes Figma’s own tracks, which is precisely why Dev Mode, Copy as, video export and the Lottie export all work on the result:
If you have not animated anything yet, the how to animate a layer along a path article walks through it, and the examples gallery has 300-odd ready-made recipes you can apply and then export immediately.
Click the … button at the right of the plugin titlebar. Six items appear.

You want Copy as code. It is the second item, above Export video.
The panel opens on CSS, because CSS is the format most people reach for first.

There are four tabs: CSS, SVG, HTML and Lottie. CSS gives you a semantic offset-path snippet where the browser interpolates the curve. SVG gives you an <animateMotion> element. HTML gives you a standalone demo page that runs the motion live in a browser. Lottie gives you the document an app build consumes.
Select Lottie. Here is the whole sequence, held a beat per step:

And the Lottie tab itself:

The line under the tabs tells you the composition length — 60 frames at 60 fps in the shot above — so you know what you are handing over before you copy it.
Two icon buttons sit in the panel header, and they act on whichever tab is selected. They produce identical content; the only difference is where it lands.
Copy is right for pasting into a ticket, a chat thread or a scratch file. Download is right when the file is going into a repository — it saves as motion-path.json with an application/json MIME type, so it arrives named correctly rather than as download.txt.
Open it and the structure is small and readable. This matters more than it sounds: a Lottie you cannot reason about is a Lottie you cannot debug when it looks wrong on a device.
The important field is ks — the layer transform. Every bit of the motion lives there, on the transform rather than in the shape. That is a deliberate design, and it is what makes the file useful: the shape inside is a placeholder sized to your object, so a developer swaps it for the real artwork, or parents their own asset to that transform, and keeps the motion untouched.
The schema version is 5.9, which is what every current player consumes.
Open the position track and you will find far more keyframes than you placed. This is not the export being wasteful, and it is worth understanding because it is the single most common question a developer asks when they first open the file.
Lottie has no equivalent of CSS’s offset-path. There is no way in the format to say “follow this curve, with this easing.” An object riding a curve simply cannot be two keyframes and a timing function — the curve has to be described.
So the path is sampled densely, and the easing is folded into when each point along it is reached. The consequence is the opposite of lossy: your easing is preserved exactly rather than approximated by whatever cubic-bézier came closest. The spacing of those keyframes is the easing.
Travel is measured by real arc length too, so a dense cluster of vertices in your original vector does not quietly slow the object down as it passes through:
The same reasoning is covered in more depth in what survives the conversion from Figma Motion to Lottie.
The plugin prints notes under the snippet listing anything in your animation that did not cross over. It does this rather than dropping things silently, which is the behaviour you want — a missing effect discovered on a device three weeks later is far more expensive than one named at export time.
The pattern is consistent. Anything riding the layer transform crosses over. Anything that lives in the artwork or on the canvas does not:
loop: true), so the JSON holds one clean pass.If your animation leans on any of those, you have two honest options: export video instead, which records exactly what the canvas plays, or rebuild that part of the effect in the player. Neither is a failure — but knowing which one you are choosing beats discovering it in QA.
This is where the file earns its keep. Lottie is not a preview format; it is a runtime one, and the same document drives four platforms.
The integration is short on every one of them:
Three things are worth saying explicitly when you send the file, because they are the questions that come back otherwise. The moving shape is a placeholder — swap it or parent real artwork to its transform. Looping is theirs to set — the JSON holds one pass. The notes list what is missing — forward them along with the file. There is a fuller version of this conversation in the developer handoff guide.
A Lottie that looks plausible in a text editor can still be wrong. The cheapest check is to load it into a real player rather than trusting the JSON.
That is how the export itself was validated: loaded into lottie-web, an object on a circular path holds a constant radius from the centre to within a fraction of a pixel, the facing sweeps a clean 360°, and the frame spacing is visibly uneven under an ease — which is exactly what “the easing is in the timing” should look like. Drop your own file into any Lottie preview tool and compare it against the plugin’s inline preview.
The preview is a fair comparison, incidentally, because it is generated from the same source as the export:
The preview, the canvas keyframes and every export come from one resolved polyline and one timing model. They cannot disagree, because there is nothing for them to disagree about.
Lottie is the right answer for an app or web build. It is the wrong answer for a Slack message, and it is overkill for a README.
If the animation is going to a person rather than a build, export video instead — Figma encodes it itself, so the file is canvas playback rather than a recording of it. MP4 is the safe default there.
No. Figma’s native Copy as produces CSS, React and JSON from a Motion animation, and Dev Mode inspects the keyframes, but there is no Lottie output in Figma itself. A plugin has to generate it. Motion Path adds it under … → Copy as code → Lottie.
Apply the motion so native keyframes exist, open the … menu in the Motion Path titlebar, choose Copy as code, select the Lottie tab, then use the copy or download icon in the panel header. The download saves motion-path.json.
Schema version 5.9, which every current Lottie player consumes — lottie-web, lottie-ios, lottie-android and lottie-react-native included.
Because Lottie has no equivalent of CSS’s offset-path, so a curve cannot be expressed as two keyframes and a timing function. The path is sampled densely and the easing is folded into the timing of each sample. The upside is that your easing is preserved exactly rather than approximated.
That is intentional. The moving layer is a placeholder sized to your object, because the motion lives on the transform rather than in the shape. A developer swaps the placeholder for the real artwork, or parents their asset to that transform, and every bit of the motion carries over.
The file holds one pass of the motion. Looping in Lottie is a player setting — loop: true in lottie-web, the loop prop in React Native, and the equivalent on iOS and Android. If your Figma animation repeats the traversal, the export notes say so.
No. Those effects live in the artwork or on the canvas rather than on the layer transform, so Lottie cannot carry them. The plugin lists any that applied to your animation in the notes under the snippet, so nothing disappears silently. If they are essential, export video instead.
Motion Path is free on the Figma Community, and the Lottie export is part of it. Install it here.
Yes — the Text tab has its own export, and it carries the letter-by-letter cascade as one Lottie layer per glyph, with the stagger baked into their timing. It is a separate export from the Animate tab’s, in the same place.
Install Motion Path — it’s free → Browse 300+ animation examples