Migrating from Lottie to ExodeUI: Interactive States Without After Effects
Step-by-step guide to migrating from passive Lottie animations to interactive ExodeUI state machines with spring physics and zero After Effects dependency.
Core Takeaway
Migrating from Lottie to ExodeUI replaces passive timeline loops with interactive vector state machines and real spring physics. Import your existing SVG vectors into the ExodeUI editor, define input triggers (booleans, numbers, triggers), and swap lottie-react for the lightweight exodeui package in your frontend codebase.
The Limits of Lottie in Modern Interaction Design
Lottie revolutionized web animation by rendering After Effects timelines via JSON. However, modern user interfaces demand two-way interactivity: buttons that respond dynamically to drag speeds, toggles that smoothly reverse mid-flight, and characters that look toward the cursor. In Lottie, achieving interactivity requires clunky segment playing (playSegments), which produces sudden cuts and rigid timing.
- Passive playback: Lottie files play linearly from frame 0 to N without internal logic.
- Fragile After Effects pipeline: Every tweak requires an AE license, Bodymovin export, and manual developer handoff.
- No spring physics: Animations are locked to baked keyframes that cannot absorb touch momentum.
Step 1: Importing Assets and Building State Machines
Export your vector graphics from Figma, Illustrator, or extract the vector shapes from your existing Lottie JSON. Drag the SVG directly into ExodeUI. Inside the editor, organize the artwork into symbols and configure state layers with spring transitions. Your animation is now an interactive state machine stored in an open .exode JSON file.
Step 2: Swapping the Runtime Package
In your project, replace @lottiefiles/react-lottie-player or lottie-react with exodeui. The ExodeUICanvas component accepts declarative inputs and fires event callbacks.
Production Implementation Snippet
// BEFORE: Rigid Lottie timeline
// import Lottie from 'lottie-react';
// <Lottie animationData={likeAnim} loop={false} />
// AFTER: Interactive ExodeUI State Machine
import React, { useState } from 'react';
import { ExodeUICanvas } from 'exodeui';
export function LikeButton() {
const [liked, setLiked] = useState(false);
return (
<button
onClick={() => setLiked(!liked)}
className="p-2 rounded-full hover:bg-neutral-800 transition"
aria-label={liked ? 'Unlike' : 'Like'}
>
<ExodeUICanvas
src="/assets/like_button.exode"
inputs={{ isLiked: liked }}
style={{ width: 32, height: 32 }}
/>
</button>
);
}