react-animated-code
v0.10.0
Published
A React component for beautifully animated code transitions using Shiki Magic Move
Maintainers
Readme
React Animated Code
A beautiful React component for animating code transitions with smooth, Fireship-style animations powered by Shiki Magic Move. Perfect for presentations, tutorials, and interactive code demonstrations.
Features
✨ Smooth Animations - Beautiful transitions between code states 🎨 Syntax Highlighting - Powered by Shiki with 100+ themes 🎬 Multi-Code Navigation - Display multiple code snippets with built-in navigation 📁 Filename Display - VS Code-style header with filename support ▶️ Auto-Play - Automatically cycle through code snippets ⚡ Fast Loading - Optimized highlighter initialization with instant fallback 📦 Zero Config - Works out of the box 🔧 TypeScript Support - Fully typed 🎯 Customizable - Control duration, stagger, themes, navigation, and more
Installation
npm install react-animated-codeQuick Start
import { AnimatedCode } from 'react-animated-code';
import 'react-animated-code/style.css';
function App() {
const codeSteps = [
"const greeting = 'Hello';",
"const greeting = 'Hello World!';",
"const greeting = 'Hello Universe!';",
];
return <AnimatedCode code={codeSteps} />;
}Props
Core Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| code | CodeInput[] | required | Array of code strings or objects with {code, filename} |
| lang | string | 'typescript' | Programming language for syntax highlighting |
| theme | string | 'github-dark' | Shiki theme name |
| className | string | '' | CSS class for container |
| duration | number | 800 | Animation duration in milliseconds |
| stagger | number | 3 | Stagger delay between animated elements |
| lineNumbers | boolean | true | Show line numbers |
Navigation Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| showControls | boolean | true | Show built-in prev/next navigation buttons |
| showFilename | boolean | true | Show filename in header bar (if provided) |
| initialIndex | number | 0 | Initial code snippet index to display |
Callbacks
| Prop | Type | Description |
|------|------|-------------|
| onNext | () => void | Called when next button is clicked |
| onPrev | () => void | Called when previous button is clicked |
| onChange | (index: number) => void | Called when the code index changes |
Auto-Play Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| autoPlay | boolean | false | Enable auto-play mode |
| autoPlayInterval | number | 3000 | Delay between auto-play transitions (ms) |
| autoPlayLoop | boolean | true | Loop back to start when reaching the end |
Examples
Basic Multi-Code Navigation
const codeSteps = [
"const x = 1;",
"const x = 2;",
"const x = 3;",
];
<AnimatedCode code={codeSteps} />With Filenames
const steps = [
{ code: "import React from 'react';", filename: "App.tsx" },
{ code: "import React, { useState } from 'react';", filename: "App.tsx" },
{ code: "import React, { useState, useEffect } from 'react';", filename: "App.tsx" },
];
<AnimatedCode code={steps} />Auto-Play for Presentations
<AnimatedCode
code={steps}
autoPlay
autoPlayInterval={4000}
duration={600}
/>Custom Theme and Language
const pythonSteps = [
"def greet():\n print('Hello')",
"def greet(name):\n print(f'Hello {name}')",
];
<AnimatedCode
code={pythonSteps}
lang="python"
theme="dracula"
duration={1000}
/>External Controls (Hide Built-in Navigation)
function CodeDemo() {
const [currentIndex, setCurrentIndex] = useState(0);
return (
<>
<AnimatedCode
code={steps}
showControls={false}
initialIndex={currentIndex}
onChange={setCurrentIndex}
/>
<div className="my-custom-controls">
<button onClick={() => setCurrentIndex(prev => Math.max(0, prev - 1))}>
Previous
</button>
<span>{currentIndex + 1} / {steps.length}</span>
<button onClick={() => setCurrentIndex(prev => Math.min(steps.length - 1, prev + 1))}>
Next
</button>
</div>
</>
);
}Tutorial-Style with Callbacks
<AnimatedCode
code={tutorialSteps}
onChange={(index) => {
console.log(`Now showing step ${index + 1}`);
// Update tutorial text, highlight UI elements, etc.
}}
onNext={() => console.log('User clicked next')}
onPrev={() => console.log('User clicked previous')}
/>Without Line Numbers
<AnimatedCode
code={steps}
lineNumbers={false}
/>Custom Styling
<AnimatedCode
code={steps}
className="my-custom-code-block"
/>Mixed String and Object Arrays
const mixedSteps = [
"console.log('Step 1');",
{ code: "console.log('Step 2');", filename: "demo.js" },
"console.log('Step 3');",
];
<AnimatedCode code={mixedSteps} />Available Themes
Popular themes include:
github-dark/github-lightnorddraculamonokaione-dark-protokyo-night
Supported Languages
Supports 100+ languages including:
- JavaScript, TypeScript, JSX, TSX
- Python, Java, C++, Rust, Go
- HTML, CSS, SCSS, JSON
- And many more...
How It Works
The component automatically:
- Eagerly initializes a Shiki syntax highlighter on module import for instant rendering
- Normalizes input - Accepts both string arrays and objects with filenames
- Manages state - Tracks current code index and auto-play status
- Calculates diffs - When navigating between code snippets, calculates the difference
- Animates transitions - Uses FLIP technique for smooth morphing animations
Lines that exist in both versions move smoothly, new lines fade in, and removed lines fade out.
Animation Behavior
- Navigation: Clicking next/prev triggers smooth code transitions
- Auto-Play: Automatically advances through code at specified intervals
- Manual Override: Auto-play pauses when user manually navigates
- Looping: Can loop back to the beginning or stop at the end
Performance
Highlighter Optimization
- Global singleton cache - Highlighters are cached and reused across components
- Eager initialization - Default highlighter loads immediately on module import
- Instant fallback - Shows styled code immediately while highlighter initializes in background
- Resource reuse - Existing highlighters can load additional themes/languages without recreation
- Zero blocking - Users see code immediately, animation upgrades happen seamlessly
Best Practices
- For presentations, use
autoPlayto create smooth, automated demonstrations - For tutorials, use
onChangecallback to sync UI with code changes - For better performance with many snippets, keep code strings reasonably sized
- Use
showControls={false}and build custom navigation for advanced UX
TypeScript Types
import type { CodeItem, CodeInput } from 'react-animated-code';
// CodeItem: Object with code and optional filename
type CodeItem = {
code: string;
filename?: string;
};
// CodeInput: Either a string or a CodeItem object
type CodeInput = string | CodeItem;
// Example usage
const steps: CodeInput[] = [
"const x = 1;",
{ code: "const x = 2;", filename: "demo.ts" },
];Browser Support
Works in all modern browsers that support ES2020.
License
MIT
Credits
Built with:
- Shiki Magic Move by Anthony Fu
- Shiki - Beautiful syntax highlighter
Contributing
Contributions are welcome! Please read our Contributing Guide for details.
Issues
Found a bug? Have a feature request? Open an issue.
