Updated September 2026. Searching for figma motion handoff for developers? The prototype felt right. The ticket says “animate like Figma.” Production ships a 400ms linear fade, shared layers jump, and nobody wrote a reduced-motion fallback. This guide is the engineer-facing spec: how to read Smart Animate, publish tokens, map to CSS or Framer Motion, and refuse a ticket that still hides intent in a prototype link.

If you need the designer-side primer on Smart Animate, transitions, and micro interactions, start with our Figma Motion explained guide. This page assumes you can open Prototype mode and want production, not another moodboard. Teams generating UI with Google Stitch AI or a vibe coding loop still need the same numbers — models invent timing even faster than humans do.
You leave with a mapping table, a smart animate to Framer Motion handoff recipe, motion tokens, and a PR checklist.
Table of contents
- What Figma motion handoff for developers actually means
- Why Smart Animate intent dies in tickets
- Figma motion design developer workflow
- Reading Figma prototype animation for engineers
- Figma Smart Animate to production (the mapping)
- Smart Animate to Framer Motion handoff
- CSS, springs, and Lottie — pick a path
- Motion tokens you can implement this week
- Developer handoff checklist
- Reduced motion is part of the spec
- Common mistakes that waste a sprint
- FAQ
- Soft CTA: accept one motion ticket this week
What Figma motion handoff for developers actually means
Figma motion handoff for developers is the process of turning prototype animation decisions into implementable constraints. It is not a screen recording. It is not “Dev Mode plus vibes.” A complete handoff names the trigger, the animation type, the duration in milliseconds, the easing or spring, the matching layers, the implementation path, and the reduced-motion fallback.
Static redlines already cover color, type, and spacing. Motion is a different product surface:
- Time — duration and delay, not “make it snappy”
- Curve — Ease Out vs Ease In vs a spring with stiffness and damping
- Continuity — shared-element morph vs a full-screen swap
- State — hover, press, loading, success, error, empty
- Accessibility — what happens when
prefers-reduced-motion: reduceis on
If any of those five are missing, engineers invent them — and the product collects seventeen unrelated timings.
Treat motion like any other design-system artifact: tokens in the ticket, not a Slack note after QA complains.
Why Smart Animate intent dies in tickets
Smart Animate interpolates layers that share a name. Designers feel continuity. Engineers see two frames and a 300ms dropdown. The intent that dies is rarely “there was an animation.” The intent that dies is which properties moved, which layers were shared, and which layers entered or exited.
Typical failure modes:
- The prototype used matching layer names; the ticket never lists them.
- Duration was 240ms Ease Out in Figma; the PR uses
transition: all 0.4s ease. - A card expand was a shared-element morph; production remounts the card and fades a new tree.
- After Delay sequences become one CSS class that animates everything at once.
- Reduced motion is left as “we will add it later,” which means never.
None of those are Figma bugs. They are spec bugs. Figma Smart Animate to production only works when someone writes the interpolation rules down in language an engineer can test.
Figma is a matching engine, not a code generator. Dev Mode will not emit a Framer Motion layoutId. Your job is translation.
Figma motion design developer workflow
A reliable figma motion design developer workflow is a loop, not a dump. Run it before the first implementation commit:
- Play the prototype at real speed on the target breakpoint. Desktop-only reviews lie about mobile timing.
- Separate critical vs decorative motion. Critical motion is acceptance criteria. Decorative motion is a nice-to-have, not a release blocker.
- Inventory interactions. Tab switch, modal open, toast, card expand, skeleton, pull-to-refresh — one row each.
- Capture tokens. Map observed durations to
fast/base/slow. Ban one-off values like 173ms unless the brand is the one-off. - Assign an implementation path — CSS, Framer Motion, native spring, or Lottie — per row.
- Write reduced-motion behavior on the same row. If you cannot describe the fallback, the interaction is not handed off.
- File the ticket with links — prototype URL, frame URL, token names, and the matching-layer list.
Same discipline as a vibe coding workflow: small units, explicit pass/fail. If an AI IDE writes the animation, paste the token row — the Crisp-E method stops the model inventing a bounce you never approved.

Reading Figma prototype animation for engineers
Figma prototype animation for engineers is a literacy skill. Open Prototype, click the connection, and read the inspector like a contract:
- Trigger — On Click, While Hovering, On Drag, After Delay, While Pressing. Map each to an event or a state machine, not to a CSS hover if the prototype used click.
- Animation type — Instant, Dissolve, Move In/Out, Push, Slide, Smart Animate. Instant means no animation, not “developer choice.”
- Direction — for Move/Push/Slide. This becomes
x/yor a clip-path, not a random fade. - Duration — Figma shows milliseconds. Copy the number. Do not “round up for safety.”
- Easing — Ease In, Ease Out, Ease In and Out, Linear, Gentle, Quick, Bouncy, Custom. Custom curves must be exported as a cubic-bezier, not described as “a little springy.”
- Overflow / overlay — overlays are not page navigations. Implement them as portals or sheets, not as a route change with a push transition.
Then switch to the layers panel. Smart Animate only interpolates identical names. If ProductImage exists on both frames, that is a shared element. If Frame B introduces CloseIcon that Frame A never had, that layer enters — opacity/transform in, not a morph. If a layer disappears, it exits. Write those three lists (shared / enter / exit) in the ticket. That single habit prevents most “it doesn’t feel like Figma” QA bugs.
Interactive components change the unit of handoff. A Button with Default / Hover / Pressed / Loading is one component spec, not four screen tickets. Hand off the component plus page-level transitions separately.
Dev Mode helps with structure and variables. It does not replace Prototype. You need both.
Figma Smart Animate to production (the mapping)
Here is the practical figma smart animate to production map we use on Vibe Coding Engineer. Steal it into your design-system docs.
| What Figma is doing | How you know | Production mapping |
|---|---|---|
| Opacity or color change | Same layer name; fill/opacity differs | CSS transition on opacity / color / background-color |
| Position or size morph | Same layer name; x/y/width/height differ | FLIP, shared-element API, or Framer Motion layout / layoutId |
| Unmatched layer appears | Name exists only on the destination frame | Mount animation: opacity + small translate, staged delay if needed |
| Unmatched layer disappears | Name exists only on the source frame | Exit animation before unmount; do not snap-remove |
| Spring / overshoot (“Bouncy”) | Easing looks physically overshot | Spring config (stiffness/damping or mass/tension) — not a CSS bounce keyword |
| After Delay sequence | Multiple connections with delays | Stagger children with explicit delay values, not one catch-all class |
| Push / Slide / Move In | Standard transition, not Smart Animate | Transform the incoming view on the axis Figma used; keep the outgoing view if Push |
| Dissolve | Crossfade, no shared-layer story | Short opacity crossfade; do not fake a morph |
Do not promise pixel-perfect Smart Animate parity on day one. Promise token-accurate timing and correct continuity. Users notice shared-element jumps and sluggish modals. They do not notice that your cubic-bezier is 0.02 off Figma’s Gentle curve.
Auto Layout rebuilds between frames are a warning: Smart Animate may dissolve more than it morphs. Implement enter/exit, not a layoutId chase Figma never performed.
Smart Animate to Framer Motion handoff
React teams ask for a smart animate to Framer Motion handoff more than any other mapping. Framer Motion is not “Figma in npm form,” but the mental model is close: variants are states, layout is shared geometry, and AnimatePresence is enter/exit for unmatched layers.
A workable recipe:
- Variants for named states. Default, Hover, Open, Success — one variant object each. Durations and easings come from tokens, not magic numbers in JSX.
layout/layoutIdfor matching layers. If Figma morphsProductImagefrom grid to detail, that image is onelayoutIdacross routes or expanded states. Do not remount it under a new React key.AnimatePresencefor unmatched layers. Overlay scrims, close icons, and toasts enter and exit. Give them an explicitexitso the DOM does not vanish on the first frame.- Springs only when Figma used a spring. Ease Out is a tween. Mapping every motion to
type: "spring"is how a design system starts bouncing like a toy. - Stagger via
transition.delayChildren/staggerChildrenwhen Figma used After Delay on a list, not a homemadesetTimeoutchain.
Write the handoff row like this so an engineer can implement without reopening every frame:
- Interaction: Product card expand to detail
- Figma: Smart Animate, 240ms, Ease Out
- Shared:
ProductImage,ProductTitle - Enter:
CloseIcon,BodyCopy - Exit:
GridMeta - Implementation: Framer Motion
layoutId="product-image"+ variants on the chrome - Reduced motion: Instant layout swap, 120ms opacity only, no layout animation
That row is the handoff. The prototype link is evidence. If a designer cannot fill the shared/enter/exit lists, the file is not ready for engineering — send it back, do not guess.
Non-React stacks use the same lists: CSS view transitions, Flutter Hero, SwiftUI matchedGeometryEffect, Android shared elements. The library changes. The spec does not.

CSS, springs, and Lottie — pick a path
Not every Figma motion moment belongs in Framer Motion. Pick a path per interaction during the workflow, not during code review.
| Path | Use when | Skip when |
|---|---|---|
| CSS transitions | Opacity, color, simple transform, one property, no unmount choreography | Shared-element morphs across routes, sequenced springs |
| CSS / WAAPI keyframes | Repeating micro-motion (shimmer, pulse) with a known duration | State-driven UI that must interrupt cleanly |
| Framer Motion (or similar) | React trees, variants, layout, presence, gestures | A 12kb library for a single button fade |
| Native springs | iOS/Android, or web when the prototype is physically springy | Enterprise admin chrome that should feel calm |
| Lottie | Illustration-heavy delight, branded loaders, mascots | UI chrome you will restyle next quarter |
Decide early. Recreating Lottie in CSS wastes a week; shipping a hover as Lottie is a performance tax. Bookmark Figma’s prototype animations, Smart Animate matching, MDN CSS transitions, and Framer Motion.
Motion tokens you can implement this week
Publish a small set and refuse one-off milliseconds. Example scale:
motion.duration.fast= 120ms — toggles, button press, icon swapsmotion.duration.base= 240ms — modals, tabs, most Smart Animate statesmotion.duration.slow= 400ms — large scene changes onlymotion.easing.enter= Ease Out (e.g.cubic-bezier(0.16, 1, 0.3, 1)or your system equivalent)motion.easing.exit= Ease Inmotion.easing.move= Ease In and Outmotion.easing.linear= progress bars and determinate loaders, not UI chrome
Put tokens in the same pipeline as color (CSS custom properties or Style Dictionary). Tickets then say motion.duration.base, not “around 250.”
Keep the set small. Three durations and a handful of easings beat a 40-token sheet nobody reads.
Developer handoff checklist
Accept a motion ticket only when every box is checked. This is the minimum figma motion handoff for developers bar:
- Prototype link points at the exact flow, not the whole file.
- Frame link (or interactive component) is in the ticket description.
- Trigger is named (click, hover, drag, delay) and matches the event you will implement.
- Animation type is named (Smart Animate, Push, Dissolve, Instant).
- Duration is a token or an explicit millisecond value copied from Figma.
- Easing is a token or an exported cubic-bezier / spring config.
- Shared / enter / exit layers are listed by name.
- Implementation path is assigned (CSS / Framer Motion / native / Lottie).
- Reduced-motion fallback is written in one sentence.
- Critical vs decorative is labeled so QA knows what blocks release.
- Assets (Lottie JSON, video) are linked with loop/autoplay/fallback rules.
- QA plan: compare production to the prototype at real device speed, not 0.5× preview.
Copy this spec block into tickets until it is muscle memory:
- Interaction name: Modal open
- Trigger: Primary button / click
- Figma animation: Move In + Smart Animate on matching layers
- Duration: 240ms (
motion.duration.base) - Easing: Ease Out (
motion.easing.enter) - Shared layers: OverlayScrim, ModalCard
- Enter / exit: ModalCard + scrim in; none out on first open
- Implementation: Framer Motion variants or CSS transform + opacity
- Reduced motion: Opacity dissolve only, 120ms max, no translate
- Links: prototype + frame
If an AI coding tool writes the first cut, paste this block as acceptance criteria. The spec stays the same regardless of editor — see the best vibe coding tools 2026 guide if you need a lane.
Reduced motion is part of the spec
Handoff that ignores prefers-reduced-motion is incomplete. WCAG’s animation from interactions guidance is the production checklist; Figma will not enforce it for you.
Practical rules engineers can implement without a debate:
- Large movement (slides, shared-element flights, parallax) becomes a short opacity dissolve or an instant cut.
- Essential feedback stays: a checkmark still appears; a toast still arrives. Only the travel is removed.
- Looping decorative motion stops. No pulsing CTAs, no ambient illustration loops.
- Duration caps at
motion.duration.fastwhen any motion remains. - Never convey information with motion alone. If a shake means “error,” the field also gets text and a color/icon change.
Write the fallback on the same ticket row as the full-motion spec. “We will respect reduced motion” is not a fallback. “No translate; 120ms opacity; icon swap still instant” is a fallback.
Common mistakes that waste a sprint
- Prototype-only handoff with no durations written down. Videos are evidence, not specs.
- One-off timings (173ms, 318ms) that never join the token scale.
- Animating
allor layout properties that trigger reflow. Prefertransformandopacity. - Remounting shared elements so Framer Motion / view transitions have nothing to interpolate.
- Using Smart Animate as a religion when Figma itself used Push or Dissolve.
- Treating decorative motion as a blocker while auth and empty states ship without feedback.
- No owner for the motion page in the design-system file, so every epic reinvents the scale.
- QA on a throttled prototype preview instead of a device at 1× speed.
The fix is boring: Dev Mode for structure, Prototype for feel, tokens for numbers, the checklist for tickets.
FAQ
What is Figma motion handoff for developers, in one sentence?
It is converting Smart Animate and prototype transitions into tokens, matching-layer lists, implementation paths, and reduced-motion fallbacks an engineer can test.
Does Figma export production-ready Smart Animate code?
No. Dev Mode helps with structure and variables. You still map interpolation to CSS, Framer Motion, native APIs, or Lottie. That mapping is the job.
How do I take Figma Smart Animate to production without guessing?
List shared, entering, and exiting layers. Copy duration and easing. Assign a path from the mapping table. QA against the prototype at real speed.
What is a clean Smart Animate to Framer Motion handoff?
Variants for states, layoutId for matching layers, AnimatePresence for unmatched enter/exit, tweens when Figma used eases, springs only when Figma used a spring.
Where should Figma prototype animation for engineers live?
In the ticket: prototype link, frame link, token names, and the shared/enter/exit lists. The Figma file is the source; the ticket is the contract.
Should every interaction use Framer Motion?
No. CSS covers simple opacity and transform. Save a library for layout, presence, and gestures. Use Lottie for illustration, not buttons. If design cannot name matching layers, the file is not ready — fix names in Figma first.
Soft CTA: accept one motion ticket this week
Pick one flow — modal, tab, or card expand. Fill the spec block. Implement with tokens. QA next to the prototype. That is a complete figma motion handoff for developers cycle.
For Smart Animate matching rules and micro-interaction patterns, keep the Figma Motion explained guide open. For the broader build loop, continue with what vibe coding is, the step-by-step workflow, and the Crisp-E prompt method when you generate animation code instead of typing it.
Intent survives when it is written down. Write it down, then ship the motion users already approved.

One thought on “Figma Motion for Developers: How to Hand Off Smart Animate Without Losing Intent”