
Rive Interactive
- 1.5k installs
- 629 repo stars
- Updated November 20, 2025
- freshtechbro/claudedesignskills
rive-interactive is an agent skill for state machine-based vector animation with runtime interactivity and web integration. use this skill when creating interactive animations, state-driven ui, animated components.
About
The rive-interactive skill is designed for state machine-based vector animation with runtime interactivity and web integration. Use this skill when creating interactive animations, state-driven UI, animated components. Rive Interactive - State Machine-Based Vector Animation Overview Rive is a state machine-based animation platform that enables designers to create interactive vector animations with complex logic and runtime interactivity. Unlike timeline-only animation tools (like Lottie), Rive supports state machines, input handling, and two-way data binding between application code and animations. Invoke when the user asks about rive interactive or related SKILL.md workflows.
- State machine system for complex interactive logic.
- ViewModel API for two-way data binding.
- Input handling (boolean, number, trigger inputs).
- Custom events for animation-to-code communication.
- Runtime property control (colors, strings, numbers, enums).
Rive Interactive by the numbers
- 1,506 all-time installs (skills.sh)
- +102 installs in the week ending Jul 29, 2026 (Skillselion tracking)
- Ranked #233 of 1,888 Design & UI/UX skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Jul 31, 2026 (Skillselion catalog sync)
rive-interactive capabilities & compatibility
- Capabilities
- state machine system for complex interactive log · viewmodel api for two way data binding · input handling (boolean, number, trigger inputs) · custom events for animation to code communicatio
- Use cases
- frontend
What rive-interactive says it does
State machine-based vector animation with runtime interactivity and web integration. Use this skill when creating interactive animations, state-driven UI, animated components with
State machine-based vector animation with runtime interactivity and web integration. Use this skill when creating interactive animations, state-driven UI, anima
npx skills add https://github.com/freshtechbro/claudedesignskills --skill rive-interactiveAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.5k |
|---|---|
| repo stars | ★ 629 |
| Security audit | 2 / 3 scanners passed |
| Last updated | November 20, 2025 |
| Repository | freshtechbro/claudedesignskills ↗ |
How do I state machine-based vector animation with runtime interactivity and web integration. use this skill when creating interactive animations, state-driven ui, animated components?
State machine-based vector animation with runtime interactivity and web integration. Use this skill when creating interactive animations, state-driven UI, animated components.
Who is it for?
Developers using rive interactive workflows documented in SKILL.md.
Skip if: Skip when the task falls outside rive-interactive scope or needs a different stack.
When should I use this skill?
User asks about rive interactive or related SKILL.md workflows.
What you get
Completed rive-interactive workflow with documented commands, files, and expected deliverables.
- rive-react component implementations
- State machine–driven interactive UI
Files
Rive Interactive - State Machine-Based Vector Animation
Overview
Rive is a state machine-based animation platform that enables designers to create interactive vector animations with complex logic and runtime interactivity. Unlike timeline-only animation tools (like Lottie), Rive supports state machines, input handling, and two-way data binding between application code and animations.
Key Features:
- State machine system for complex interactive logic
- ViewModel API for two-way data binding
- Input handling (boolean, number, trigger inputs)
- Custom events for animation-to-code communication
- Runtime property control (colors, strings, numbers, enums)
- Cross-platform support (Web, React, React Native, iOS, Android, Flutter)
- Small file sizes with vector graphics
When to Use This Skill:
- Creating UI animations with complex state transitions
- Building interactive animated components (buttons, toggles, loaders)
- Implementing game-like UI with state-driven animations
- Binding real-time data to animated visualizations
- Creating animations that respond to user input
- Working with designer-created animations requiring runtime control
Alternatives:
- Lottie (lottie-animations): For simpler timeline-based animations without state machines
- Framer Motion (motion-framer): For code-first React animations with spring physics
- GSAP (gsap-scrolltrigger): For timeline-based web animations with precise control
Core Concepts
1. State Machines
State machines define animation behavior with states and transitions:
- States: Different animation states (e.g., idle, hover, pressed)
- Inputs: Variables that control transitions (boolean, number, trigger)
- Transitions: Rules for moving between states
- Listeners: React hooks to respond to state changes
2. Inputs
Three input types control state machine behavior:
- Boolean: On/off states (e.g., isHovered, isActive)
- Number: Numeric values (e.g., progress, volume)
- Trigger: One-time events (e.g., click, submit)
3. ViewModels
Data binding system for dynamic properties:
- String Properties: Text content (e.g., username, title)
- Number Properties: Numeric data (e.g., stock price, score)
- Color Properties: Dynamic colors (hex values)
- Enum Properties: Selection from predefined options
- Trigger Properties: Animation events
4. Events
Custom events emitted from animations:
- General Events: Custom named events
- Event Properties: Data attached to events
- Event Listeners: React hooks to handle events
Common Patterns
Pattern 1: Basic Rive Animation
Use Case: Display a simple Rive animation in React
Implementation:
# Installation
npm install rive-reactimport Rive from 'rive-react';
export default function SimpleAnimation() {
return (
<Rive
src="animation.riv"
artboard="Main"
animations="idle"
layout={{ fit: "contain", alignment: "center" }}
style={{ width: '400px', height: '400px' }}
/>
);
}Key Points:
src: Path to .riv fileartboard: Which artboard to displayanimations: Which animation timeline to playlayout: How animation fits in container
Pattern 2: State Machine Control with Inputs
Use Case: Control animation states based on user interaction
Implementation:
import { useRive, useStateMachineInput } from 'rive-react';
export default function InteractiveButton() {
const { rive, RiveComponent } = useRive({
src: 'button.riv',
stateMachines: 'Button State Machine',
autoplay: true,
});
// Get state machine inputs
const hoverInput = useStateMachineInput(
rive,
'Button State Machine',
'isHovered',
false
);
const clickInput = useStateMachineInput(
rive,
'Button State Machine',
'isClicked',
false
);
return (
<div
onMouseEnter={() => hoverInput && (hoverInput.value = true)}
onMouseLeave={() => hoverInput && (hoverInput.value = false)}
onClick={() => clickInput && clickInput.fire()} // Trigger input
style={{ cursor: 'pointer' }}
>
<RiveComponent style={{ width: '200px', height: '100px' }} />
</div>
);
}Input Types:
- Boolean:
input.value = true/false - Number:
input.value = 50 - Trigger:
input.fire()
Pattern 3: ViewModel Data Binding
Use Case: Bind application data to animation properties
Implementation:
import { useRive, useViewModel, useViewModelInstance,
useViewModelInstanceString, useViewModelInstanceNumber } from 'rive-react';
import { useEffect, useState } from 'react';
export default function Dashboard() {
const [stockPrice, setStockPrice] = useState(150.0);
const { rive, RiveComponent } = useRive({
src: 'dashboard.riv',
autoplay: true,
autoBind: false, // Manual binding for ViewModels
});
// Get ViewModel and instance
const viewModel = useViewModel(rive, { name: 'Dashboard' });
const viewModelInstance = useViewModelInstance(viewModel, { rive });
// Bind properties
const { setValue: setTitle } = useViewModelInstanceString(
'title',
viewModelInstance
);
const { setValue: setPrice } = useViewModelInstanceNumber(
'stockPrice',
viewModelInstance
);
useEffect(() => {
if (setTitle) setTitle('Stock Dashboard');
}, [setTitle]);
useEffect(() => {
if (setPrice) setPrice(stockPrice);
}, [setPrice, stockPrice]);
// Simulate real-time updates
useEffect(() => {
const interval = setInterval(() => {
setStockPrice((prev) => prev + (Math.random() - 0.5) * 10);
}, 1000);
return () => clearInterval(interval);
}, []);
return <RiveComponent style={{ width: '800px', height: '600px' }} />;
}ViewModel Property Hooks:
useViewModelInstanceString- Text propertiesuseViewModelInstanceNumber- Numeric propertiesuseViewModelInstanceColor- Color properties (hex)useViewModelInstanceEnum- Enum selectionuseViewModelInstanceTrigger- Animation triggers
Pattern 4: Handling Rive Events
Use Case: React to events emitted from Rive animation
Implementation:
import { useRive, EventType, RiveEventType } from 'rive-react';
import { useEffect } from 'react';
export default function InteractiveRating() {
const { rive, RiveComponent } = useRive({
src: 'rating.riv',
stateMachines: 'State Machine 1',
autoplay: true,
automaticallyHandleEvents: true,
});
useEffect(() => {
if (!rive) return;
const onRiveEvent = (event) => {
const eventData = event.data;
if (eventData.type === RiveEventType.General) {
console.log('Event:', eventData.name);
// Access event properties
const rating = eventData.properties.rating;
const message = eventData.properties.message;
if (rating >= 4) {
alert(`Thanks for ${rating} stars: ${message}`);
}
}
};
rive.on(EventType.RiveEvent, onRiveEvent);
return () => {
rive.off(EventType.RiveEvent, onRiveEvent);
};
}, [rive]);
return <RiveComponent style={{ width: '400px', height: '300px' }} />;
}Pattern 5: Preloading Rive Files
Use Case: Optimize load times by preloading animations
Implementation:
import { useRiveFile, useRive } from 'rive-react';
export default function PreloadedAnimation() {
const { riveFile, status } = useRiveFile({
src: 'large-animation.riv',
});
const { RiveComponent } = useRive({
riveFile: riveFile,
artboard: 'Main',
autoplay: true,
});
if (status === 'loading') {
return <div>Loading animation...</div>;
}
if (status === 'failed') {
return <div>Failed to load animation</div>;
}
return <RiveComponent style={{ width: '600px', height: '400px' }} />;
}Pattern 6: Controlled Animation with Refs
Use Case: Control animation from parent component
Implementation:
import { useRive, useViewModel, useViewModelInstance,
useViewModelInstanceTrigger } from 'rive-react';
import { useImperativeHandle, forwardRef } from 'react';
const AnimatedComponent = forwardRef((props, ref) => {
const { rive, RiveComponent } = useRive({
src: 'logo.riv',
autoplay: true,
autoBind: false,
});
const viewModel = useViewModel(rive, { useDefault: true });
const viewModelInstance = useViewModelInstance(viewModel, { rive });
const { trigger: spinTrigger } = useViewModelInstanceTrigger(
'triggerSpin',
viewModelInstance
);
// Expose methods to parent
useImperativeHandle(ref, () => ({
spin: () => spinTrigger && spinTrigger(),
pause: () => rive && rive.pause(),
play: () => rive && rive.play(),
}));
return <RiveComponent style={{ width: '200px', height: '200px' }} />;
});
export default function App() {
const animationRef = useRef();
return (
<div>
<AnimatedComponent ref={animationRef} />
<button onClick={() => animationRef.current?.spin()}>Spin</button>
<button onClick={() => animationRef.current?.pause()}>Pause</button>
</div>
);
}Pattern 7: Multi-Property ViewModel Updates
Use Case: Update multiple animation properties from complex data
Implementation:
import { useRive, useViewModel, useViewModelInstance,
useViewModelInstanceString, useViewModelInstanceNumber,
useViewModelInstanceColor } from 'rive-react';
import { useEffect } from 'react';
export default function UserProfile({ user }) {
const { rive, RiveComponent } = useRive({
src: 'profile.riv',
autoplay: true,
autoBind: false,
});
const viewModel = useViewModel(rive, { useDefault: true });
const viewModelInstance = useViewModelInstance(viewModel, { rive });
// Bind all properties
const { setValue: setName } = useViewModelInstanceString('name', viewModelInstance);
const { setValue: setScore } = useViewModelInstanceNumber('score', viewModelInstance);
const { setValue: setColor } = useViewModelInstanceColor('avatarColor', viewModelInstance);
useEffect(() => {
if (user && setName && setScore && setColor) {
setName(user.name);
setScore(user.score);
setColor(parseInt(user.color.substring(1), 16)); // Convert hex to number
}
}, [user, setName, setScore, setColor]);
return <RiveComponent style={{ width: '300px', height: '300px' }} />;
}Integration Patterns
With Framer Motion (motion-framer)
Animate container while Rive handles interactive content:
import { motion } from 'framer-motion';
import Rive from 'rive-react';
export default function AnimatedCard() {
return (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
whileHover={{ scale: 1.05 }}
>
<Rive
src="card.riv"
stateMachines="Card State Machine"
style={{ width: '300px', height: '400px' }}
/>
</motion.div>
);
}With GSAP ScrollTrigger (gsap-scrolltrigger)
Trigger Rive animations on scroll:
import { useRive, useStateMachineInput } from 'rive-react';
import { useEffect, useRef } from 'react';
import gsap from 'gsap';
import ScrollTrigger from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
export default function ScrollRive() {
const containerRef = useRef();
const { rive, RiveComponent } = useRive({
src: 'scroll-animation.riv',
stateMachines: 'State Machine 1',
autoplay: true,
});
const trigger = useStateMachineInput(rive, 'State Machine 1', 'trigger');
useEffect(() => {
if (!trigger) return;
ScrollTrigger.create({
trigger: containerRef.current,
start: 'top center',
onEnter: () => trigger.fire(),
});
}, [trigger]);
return (
<div ref={containerRef}>
<RiveComponent style={{ width: '100%', height: '600px' }} />
</div>
);
}Performance Optimization
1. Use Off-Screen Renderer
<Rive
src="animation.riv"
useOffscreenRenderer={true} // Better performance
/>2. Optimize Rive Files
In Rive Editor:
- Keep artboards under 2MB
- Use vector graphics (avoid raster images when possible)
- Minimize number of bones in skeletal animations
- Reduce complexity of state machines
3. Preload Critical Animations
const { riveFile } = useRiveFile({ src: 'critical.riv' });
// Preload during app initialization4. Disable Automatic Event Handling
<Rive
src="animation.riv"
automaticallyHandleEvents={false} // Manual control
/>Common Pitfalls and Solutions
Pitfall 1: State Machine Input Not Found
Problem: useStateMachineInput returns null
Solution:
// ❌ Wrong: Incorrect input name
const input = useStateMachineInput(rive, 'State Machine', 'wrongName');
// ✅ Correct: Match exact name from Rive editor
const input = useStateMachineInput(rive, 'State Machine', 'isHovered');
// Always check if input exists before using
if (input) {
input.value = true;
}Pitfall 2: ViewModel Property Not Updating
Problem: ViewModel property doesn't update animation
Solution:
// ❌ Wrong: autoBind enabled
const { rive } = useRive({
src: 'dashboard.riv',
autoplay: true,
// autoBind: true (default)
});
// ✅ Correct: Disable autoBind for ViewModels
const { rive } = useRive({
src: 'dashboard.riv',
autoplay: true,
autoBind: false, // Required for manual ViewModel control
});Pitfall 3: Event Listener Not Firing
Problem: Rive events not triggering callback
Solution:
// ❌ Wrong: Missing automaticallyHandleEvents
const { rive } = useRive({
src: 'rating.riv',
stateMachines: 'State Machine 1',
autoplay: true,
});
// ✅ Correct: Enable event handling
const { rive } = useRive({
src: 'rating.riv',
stateMachines: 'State Machine 1',
autoplay: true,
automaticallyHandleEvents: true, // Required for events
});Resources
Official Documentation
- Rive Docs: https://rive.app/docs
- React Rive GitHub: https://github.com/rive-app/rive-react
- Rive Community: https://rive.app/community
Rive Editor
- Web Editor: https://rive.app/community
- Desktop App: Available for macOS, Windows
Learning Resources
- Tutorials: https://rive.app/learn
- Examples: https://rive.app/community/files
- State Machine Guide: https://rive.app/docs/state-machine
Related Skills
- lottie-animations: For simpler timeline-based animations without state machines
- motion-framer: For code-first React animations with gestures
- gsap-scrolltrigger: For scroll-driven animations
- spline-interactive: For 3D interactive animations
Scripts
This skill includes utility scripts:
component_generator.py- Generate Rive React component boilerplateviewmodel_builder.py- Build ViewModel property bindings
Run scripts from the skill directory:
./scripts/component_generator.py
./scripts/viewmodel_builder.pyAssets
Starter templates and examples:
starter_rive/- Complete React + Rive templateexamples/- Real-world integration patterns
Rive Interactive - Assets
Starter templates and examples for Rive + React integration.
Quick Start
npm install rive-reactBasic Usage
import Rive from 'rive-react';
<Rive
src="animation.riv"
stateMachines="State Machine 1"
style={{ width: '400px', height: '400px' }}
/>State Machine Example
import { useRive, useStateMachineInput } from 'rive-react';
export default function InteractiveButton() {
const { rive, RiveComponent } = useRive({
src: 'button.riv',
stateMachines: 'Button State Machine',
autoplay: true,
});
const hoverInput = useStateMachineInput(rive, 'Button State Machine', 'isHovered', false);
return (
<div
onMouseEnter={() => hoverInput && (hoverInput.value = true)}
onMouseLeave={() => hoverInput && (hoverInput.value = false)}
>
<RiveComponent style={{ width: '200px', height: '100px' }} />
</div>
);
}ViewModel Example
import { useRive, useViewModel, useViewModelInstance,
useViewModelInstanceString } from 'rive-react';
import { useEffect } from 'react';
export default function Dashboard({ title }) {
const { rive, RiveComponent } = useRive({
src: 'dashboard.riv',
autoplay: true,
autoBind: false,
});
const viewModel = useViewModel(rive, { useDefault: true });
const instance = useViewModelInstance(viewModel, { rive });
const { setValue: setTitle } = useViewModelInstanceString('title', instance);
useEffect(() => {
if (setTitle) setTitle(title);
}, [title, setTitle]);
return <RiveComponent style={{ width: '800px', height: '600px' }} />;
}Resources
Rive React API Reference
Complete API reference for rive-react library.
Installation
npm install rive-reactHooks
useRive
Main hook for initializing Rive animations.
const { rive, RiveComponent } = useRive(options);Options:
src(string): Path to .riv fileriveFile(File): Preloaded Rive fileartboard(string): Artboard nameanimations(string | string[]): Animations to playstateMachines(string | string[]): State machines to activatelayout(Layout): Fit and alignment optionsautoplay(boolean): Auto-play animations (default: true)autoBind(boolean): Auto-bind ViewModels (default: true)automaticallyHandleEvents(boolean): Handle Rive eventsuseOffscreenRenderer(boolean): Use off-screen renderershouldResizeCanvasToContainer(boolean): Auto-resize canvas
useStateMachineInput
Get state machine input reference.
const input = useStateMachineInput(rive, stateMachineName, inputName, initialValue);Input Types:
- Boolean:
input.value = true/false - Number:
input.value = 50 - Trigger:
input.fire()
useViewModel
Get ViewModel reference.
const viewModel = useViewModel(rive, { name: 'ViewModelName' });
// Or use default ViewModel
const viewModel = useViewModel(rive, { useDefault: true });useViewModelInstance
Get or create ViewModel instance.
// Get default instance
const instance = useViewModelInstance(viewModel, { rive });
// Get named instance
const instance = useViewModelInstance(viewModel, { name: 'Instance1' });
// Create new instance
const instance = useViewModelInstance(viewModel, { useNew: true, rive });useViewModelInstanceString
Bind string property.
const { value, setValue } = useViewModelInstanceString('propertyName', instance);useViewModelInstanceNumber
Bind number property.
const { value, setValue } = useViewModelInstanceNumber('propertyName', instance);useViewModelInstanceColor
Bind color property (hex number).
const { value, setValue } = useViewModelInstanceColor('propertyName', instance);
// Set color
setValue(0xff6b6b); // Hex number, no #useViewModelInstanceEnum
Bind enum property.
const { value, setValue } = useViewModelInstanceEnum('propertyName', instance);useViewModelInstanceTrigger
Fire or listen to trigger events.
// Fire trigger
const { trigger } = useViewModelInstanceTrigger('triggerName', instance);
trigger();
// Listen to trigger
useViewModelInstanceTrigger('triggerName', instance, {
onTrigger: () => console.log('Triggered!')
});useRiveFile
Preload Rive file.
const { riveFile, status } = useRiveFile({ src: 'animation.riv' });
// status: 'loading' | 'success' | 'failed'Components
Rive Component
Declarative component for simple use cases.
import Rive from 'rive-react';
<Rive
src="animation.riv"
artboard="Main"
animations="idle"
stateMachines="State Machine 1"
layout={{ fit: "contain", alignment: "center" }}
useOffscreenRenderer={true}
shouldResizeCanvasToContainer={true}
automaticallyHandleEvents={false}
style={{ width: '400px', height: '400px' }}
/>RiveComponent (from useRive)
Component returned by useRive hook.
const { RiveComponent } = useRive({ src: 'animation.riv' });
<RiveComponent style={{ width: '400px', height: '400px' }} />Events
EventType
import { EventType } from 'rive-react';
EventType.Load // Rive file loaded
EventType.Play // Animation started
EventType.Pause // Animation paused
EventType.Stop // Animation stopped
EventType.Loop // Animation looped
EventType.Draw // Frame drawn
EventType.RiveEvent // Custom Rive eventRiveEventType
import { RiveEventType } from 'rive-react';
RiveEventType.General // General custom event
RiveEventType.OpenUrl // Open URL eventEvent Listening
useEffect(() => {
if (!rive) return;
const onRiveEvent = (event) => {
const eventData = event.data;
if (eventData.type === RiveEventType.General) {
console.log('Event:', eventData.name);
console.log('Properties:', eventData.properties);
}
};
rive.on(EventType.RiveEvent, onRiveEvent);
return () => {
rive.off(EventType.RiveEvent, onRiveEvent);
};
}, [rive]);Layout Options
interface Layout {
fit?: 'contain' | 'cover' | 'fill' | 'fitWidth' | 'fitHeight' | 'none' | 'scaleDown';
alignment?: 'center' | 'topLeft' | 'topCenter' | 'topRight' | 'centerLeft' |
'centerRight' | 'bottomLeft' | 'bottomCenter' | 'bottomRight';
}Rive Instance Methods
From useRive hook:
rive.play() // Play animation
rive.pause() // Pause animation
rive.stop() // Stop animation
rive.reset() // Reset animation
rive.cleanup() // Cleanup resources
rive.resizeDrawingSurfaceToCanvas() // Resize canvasTypeScript Support
import { useRive, useStateMachineInput, Layout } from 'rive-react';
interface Props {
animationSrc: string;
}
const MyComponent: React.FC<Props> = ({ animationSrc }) => {
const { rive, RiveComponent } = useRive({
src: animationSrc,
autoplay: true,
});
const hoverInput = useStateMachineInput(
rive,
'State Machine',
'isHovered',
false
);
return <RiveComponent />;
};Common Patterns
Dynamic Animation Switching
const [animation, setAnimation] = useState('idle');
const { RiveComponent } = useRive({
src: 'character.riv',
animations: animation,
autoplay: true,
});
// Change animation
<button onClick={() => setAnimation('walk')}>Walk</button>Multiple State Machines
const { rive, RiveComponent } = useRive({
src: 'animation.riv',
stateMachines: ['State Machine 1', 'State Machine 2'],
autoplay: true,
});Responsive Layout
const layout = {
fit: window.innerWidth < 768 ? 'fitWidth' : 'contain',
alignment: 'center'
};
<Rive src="animation.riv" layout={layout} />Error Handling
const { rive, RiveComponent } = useRive({
src: 'animation.riv',
autoplay: true,
});
if (!rive) {
return <div>Loading animation...</div>;
}
return <RiveComponent />;Performance Tips
1. Use Off-Screen Renderer:
<Rive useOffscreenRenderer={true} />2. Preload Files:
const { riveFile } = useRiveFile({ src: 'animation.riv' });3. Disable Auto-Resize:
<Rive shouldResizeCanvasToContainer={false} />4. Manual Event Handling:
<Rive automaticallyHandleEvents={false} />#!/usr/bin/env python3
"""
Rive Component Generator
Generate Rive React component boilerplate.
Usage:
./component_generator.py # Interactive mode
"""
print("""
# Rive Component Template
```jsx
import { useRive, useStateMachineInput } from 'rive-react';
export default function RiveComponent() {
const { rive, RiveComponent } = useRive({
src: 'animation.riv',
stateMachines: 'State Machine 1',
autoplay: true,
});
const input = useStateMachineInput(
rive,
'State Machine 1',
'inputName',
false
);
return (
<RiveComponent style={{ width: '400px', height: '400px' }} />
);
}
```
Visit https://rive.app/docs for more information.
""")
#!/usr/bin/env python3
"""
Rive ViewModel Builder
Generate ViewModel property binding code.
Usage:
./viewmodel_builder.py # Interactive mode
"""
print("""
# Rive ViewModel Template
```jsx
import { useRive, useViewModel, useViewModelInstance,
useViewModelInstanceString, useViewModelInstanceNumber } from 'rive-react';
import { useEffect } from 'react';
export default function ViewModelComponent({ data }) {
const { rive, RiveComponent } = useRive({
src: 'animation.riv',
autoplay: true,
autoBind: false, // Required for ViewModels
});
const viewModel = useViewModel(rive, { useDefault: true });
const instance = useViewModelInstance(viewModel, { rive });
const { setValue: setTitle } = useViewModelInstanceString('title', instance);
const { setValue: setValue } = useViewModelInstanceNumber('value', instance);
useEffect(() => {
if (setTitle && setValue) {
setTitle(data.title);
setValue(data.value);
}
}, [data, setTitle, setValue]);
return <RiveComponent style={{ width: '600px', height: '400px' }} />;
}
```
Visit https://rive.app/docs/viewmodel for more information.
""")
Related skills
How it compares
Use rive-interactive for runtime-interactive vector motion in React; use muapi-ui-design when the need is static mockups rather than animated components.
FAQ
What does rive-interactive do?
State machine-based vector animation with runtime interactivity and web integration. Use this skill when creating interactive animations, state-driven UI, animated components.
When should I use rive-interactive?
User asks about rive interactive or related SKILL.md workflows.
Is rive-interactive safe to install?
Review the Security Audits panel on this page before installing in production.