A CLI tool for generating images and videos from JSX templates using Tailwind CSS and Satori. Templates live in a .loopwind/ directory alongside your codebase.
Quick Start
Loopwind is a CLI tool for generating images and videos with React and Tailwind CSS. It's designed to be used with AI Agents and Cursor.
Installation
CODEBLOCK0
This installs loopwind to ~/.loopwind/ and adds the loopwind command to your PATH. Requires Node.js 18+.
Initialize in Your Project
Navigate to any project folder and run:
CODEBLOCK1
This creates .loopwind/loopwind.json — a configuration file with your project's theme colors.
Install AI Skill
Give your AI agent expertise in loopwind:
CODEBLOCK2
This installs a skill that teaches Claude Code (or other AI agents) how to create templates, use animation classes, and render images/videos.
Use with Claude Code
With the loopwind skill installed, Claude has deep knowledge of template structure, animation classes, and Tailwind CSS patterns for Satori. Just ask:
CODEBLOCK3
CODEBLOCK4
Claude will create optimized templates and render the final output automatically.
Install a Template
1. Official Templates
CODEBLOCK5
Templates are installed to: INLINECODE4
Benefits:
- Templates are local to your project
Version controlled with your project
Easy to share within your team
Render a Template
CODEBLOCK6
or use a local props file:
CODEBLOCK7
Commands
loopwind add <source>
Install a template from various sources:
CODEBLOCK8
These will be downloaded to INLINECODE6
loopwind list
List all installed templates:
CODEBLOCK9
loopwind render <template> <props> [options]
Render an image or video:
CODEBLOCK10
Options:
- --out, -o - Output filename (default: <template>.<ext> in current directory)
Templates are React components that define your images and videos. They use Tailwind CSS for styling and export metadata that loopwind uses for rendering.
Installing Templates
Official Templates
CODEBLOCK14
Templates are installed to .loopwind/<template-name>/.
Layouts let you wrap templates with consistent headers, footers, and styling. A child template specifies a layout in its meta, and the layout receives the child content as a children prop.
Basic Usage
Layout Template
Create a layout template that receives children:
CODEBLOCK26
Usage in Templates
Reference the layout using a relative path:
CODEBLOCK27
Render
CODEBLOCK28
The output uses the layout's size (1200x630) with the child content inside.
Key Concepts
Size
When using a layout, the layout's size controls the final output dimensions. The child template doesn't need a size property.
Path Resolution
Use relative paths to reference layouts:
CODEBLOCK29
Props Flow
The layout receives:
- All standard helpers (tw, image, qr, template, etc.)
INLINECODE34 prop containing the rendered child content
Animation context (frame, progress) for video layouts
CODEBLOCK30
Video Layouts
Layouts work with video templates. Both the layout and child can use animations:
loopwind provides Tailwind-style animation classes that work with time to create smooth video animations without writing custom code.
Note: Animation classes only work with video templates and GIFs. For static images, animations will have no effect since there's no time context.
Quick Start
CODEBLOCK42
Animation Format
loopwind uses three types of animations with millisecond timing:
Type
Format
Description
Enter
INLINECODE47
Animations that play when entering
Exit
exit-{type}/{start}/{duration} | Animations that play when exiting |
| Loop | loop-{type}/{duration} | Continuous looping animations |
All timing values are in milliseconds (1000ms = 1 second).
Utility-Based Animations
In addition to predefined animations, loopwind supports Tailwind utility-based animations that let you animate any transform or opacity property directly:
CODEBLOCK43
Supported Utilities
Utility
Format
Description
Example
translate-x
INLINECODE50
Translate horizontally
INLINECODE51 = 20px<br/>enter-translate-x-full = 100%<br/>enter-translate-x-[20px] = 20px
translate-y
enter-translate-y-{value} | Translate vertically | loop-translate-y-10 = 40px enter-translate-y-1/2 = 50% enter-translate-y-[5rem] = 80px |
| opacity | enter-opacity-{n} | Set opacity (0-100) | enter-opacity-50 = 50% |
| scale | enter-scale-{n} | Scale element (0-200) | enter-scale-100 = 1.0x |
| rotate | enter-rotate-{n} | Rotate in degrees | enter-rotate-45 = 45° |
| skew-x | enter-skew-x-{n} | Skew on X axis in degrees | enter-skew-x-12 = 12° |
| skew-y | enter-skew-y-{n} | Skew on Y axis in degrees | exit-skew-y-6 = 6° |
Translate value formats:
- Numeric: 5 = 20px (Tailwind spacing scale: 1 unit = 4px)
You can combine multiple utility animations on the same element:
CODEBLOCK49
Bracket Notation
For more CSS-like syntax, you can use brackets with units:
CODEBLOCK50
Enter Animations
Format: INLINECODE85
- startMs - when the animation begins (milliseconds from start)
INLINECODE87 - how long the animation lasts
When values are omitted (enter-fade-in), it uses the full video duration.
Fade Animations
Simple opacity transitions with optional direction.
CODEBLOCK51
Class
Description
INLINECODE89
Fade in (opacity 0 → 1)
INLINECODE90
Fade in + slide up (30px) |
| enter-fade-in-down/0/500 | Fade in + slide down (30px) |
| enter-fade-in-left/0/500 | Fade in + slide from left (30px) |
| enter-fade-in-right/0/500 | Fade in + slide from right (30px) |
Slide Animations
Larger movement (100px) with fade.
CODEBLOCK52
Class
Description
INLINECODE94
Slide in from left (100px)
INLINECODE95
Slide in from right (100px) |
| enter-slide-up/0/500 | Slide in from bottom (100px) |
| enter-slide-down/0/500 | Slide in from top (100px) |
Bounce Animations
Playful entrance with overshoot effect.
CODEBLOCK53
Class
Description
INLINECODE98
Bounce in with scale overshoot
INLINECODE99
Bounce in from below |
| enter-bounce-in-down/0/500 | Bounce in from above |
| enter-bounce-in-left/0/500 | Bounce in from left |
| enter-bounce-in-right/0/500 | Bounce in from right |
Scale & Zoom Animations
Size-based transitions.
CODEBLOCK54
Class
Description
INLINECODE103
Scale up from 50% to 100%
INLINECODE104
Zoom in from 0% to 100% |
Rotate & Flip Animations
Rotation-based transitions.
CODEBLOCK55
Class
Description
INLINECODE105
Rotate in from -180°
INLINECODE106
3D flip on horizontal axis |
| enter-flip-in-y/0/500 | 3D flip on vertical axis |
Exit Animations
Format: INLINECODE108
- startMs - when the exit animation begins
INLINECODE110 - how long the exit animation lasts
Exit animations use the same timing system but animate elements out.
CODEBLOCK56
Class
Description
INLINECODE111
Fade out (opacity 1 → 0)
INLINECODE112
Fade out + slide up |
| exit-fade-out-down/2500/500 | Fade out + slide down |
| exit-fade-out-left/2500/500 | Fade out + slide left |
| exit-fade-out-right/2500/500 | Fade out + slide right |
| exit-slide-up/2500/500 | Slide out upward (100px) |
| exit-slide-down/2500/500 | Slide out downward (100px) |
| exit-slide-left/2500/500 | Slide out to left (100px) |
| exit-slide-right/2500/500 | Slide out to right (100px) |
| exit-scale-out/2500/500 | Scale out to 150% |
| exit-zoom-out/2500/500 | Zoom out to 200% |
| exit-rotate-out/2500/500 | Rotate out to 180° |
| exit-bounce-out/2500/500 | Bounce out with scale |
| exit-bounce-out-up/2500/500 | Bounce out upward |
| exit-bounce-out-down/2500/500 | Bounce out downward |
| exit-bounce-out-left/2500/500 | Bounce out to left |
| exit-bounce-out-right/2500/500 | Bounce out to right |
Loop Animations
Format: INLINECODE128
Loop animations repeat every {durationMs} milliseconds:
- /1000 = 1 second loop
INLINECODE131 = 0.5 second loop
INLINECODE132 = 2 second loop
When duration is omitted (loop-bounce), it defaults to 1000ms (1 second).
CODEBLOCK57
Class
Description
INLINECODE134
Opacity pulse (0.5 → 1 → 0.5)
INLINECODE135
Bounce up and down |
| loop-spin/{ms} | Full 360° rotation |
| loop-ping/{ms} | Scale up + fade out (radar effect) |
| loop-wiggle/{ms} | Side to side wiggle |
| loop-float/{ms} | Gentle up and down floating |
| loop-pulse/{ms} | Scale pulse (1.0 → 1.05 → 1.0) |
| loop-shake/{ms} | Shake side to side |
Easing Functions
Add an easing class before the animation class to control the timing curve.
CODEBLOCK58
Class
Description
Best For
INLINECODE142
Constant speed
Mechanical motion
INLINECODE143
Slow start, fast end | Exit animations |
| ease-out | Fast start, slow end (default) | Enter animations |
| ease-in-out | Slow start and end | Subtle transitions |
| ease-in-cubic | Strong slow start | Dramatic exits |
| ease-out-cubic | Strong fast start | Impactful entrances |
| ease-in-out-cubic | Strong both ends | Emphasis animations |
| ease-in-quart | Very strong slow start | Powerful exits |
| ease-out-quart | Very strong fast start | Punchy entrances |
| ease-in-out-quart | Very strong both ends | Maximum drama |
Per-Animation-Type Easing
You can apply different easing functions to enter, exit, and loop animations on the same element using enter-ease-*, exit-ease-*, and loop-ease-* classes.
CODEBLOCK59
How it works:
1. Default easing (ease-*) applies to ALL animations if no specific override is set
Specific easing (enter-ease-*, exit-ease-*, loop-ease-*) overrides the default for that animation type
If both are present, specific easing takes priority for its animation type
Spring easing creates natural, physics-based bouncy animations. Use the built-in ease-spring easing or create custom springs with configurable parameters.
CODEBLOCK60
Spring parameters:
Parameter
Description
Effect when increased
Default
mass
Mass of the spring
Slower, more inertia
1
stiffness
Spring stiffness | Faster, snappier | 100 |
| damping | Damping coefficient | Less bounce, smoother | 10 |
Common spring presets:
CODEBLOCK61
How spring works:
1. Default ease-spring - Uses a pre-calculated spring curve optimized for most use cases
Custom ease-spring/mass/stiffness/damping - Generates a physics-based spring curve using the damped harmonic oscillator formula
The spring automatically calculates its ideal duration to reach the final state
Works with all animation types: ease-spring, enter-ease-spring, exit-ease-spring, INLINECODE209
Combining Enter and Exit
You can use both enter and exit animations on the same element:
CODEBLOCK62
The opacities from multiple animations are multiplied together, so you get smooth transitions that combine properly.
Staggered Animations
Create sequenced animations by offsetting start times:
CODEBLOCK63
Dynamic Staggering
For dynamic lists, calculate the timing programmatically:
CODEBLOCK64
Common Patterns
Intro Sequence
CODEBLOCK65
Text Reveal
CODEBLOCK66
Looping Background Element
CODEBLOCK67
Full Enter/Exit Animation
CODEBLOCK68
Programmatic Animations
For complete control beyond animation classes, use progress and frame directly.
Available Props
Prop
Type
Description
INLINECODE212
INLINECODE213
0 to 1 through the video (0% to 100%)
INLINECODE214
number | Current frame number (0, 1, 2, ... totalFrames-1) |
These are only available in video templates. Use them when animation classes aren't flexible enough.
Using frame
CODEBLOCK69
Using progress
CODEBLOCK70
Custom Easing
CODEBLOCK71
When to Use Programmatic Animations
Use progress/frame instead of animation classes when you need:
- Custom easing functions (elastic, bounce with specific curves beyond built-in ease-spring)