@mihirsarya/manim-scroll-next
v0.2.2
Published
Next.js plugin for build-time Manim scroll animation rendering.
Readme
@mihirsarya/manim-scroll-next
Next.js plugin for build-time Manim scroll animation rendering. Automatically scans your source files, extracts <ManimScroll> components, and renders animations with smart caching.
Installation
npm install @mihirsarya/manim-scroll-nextOr use the unified package (recommended):
npm install @mihirsarya/manim-scrollRequirements
- Next.js 13+
- Python 3.8+ with Manim installed
Quick Start
1. Configure Next.js
// next.config.js
const { withManimScroll } = require("@mihirsarya/manim-scroll-next");
// Or: const { withManimScroll } = require("@mihirsarya/manim-scroll/next");
module.exports = withManimScroll({
manimScroll: {
pythonPath: "python3",
quality: "h",
},
});2. Use ManimScroll Components
// app/page.tsx
import { ManimScroll } from "@mihirsarya/manim-scroll-react";
// Or: import { ManimScroll } from "@mihirsarya/manim-scroll";
export default function Home() {
return (
<ManimScroll
scene="TextScene"
fontSize={72}
color="#ffffff"
>
Welcome to my site
</ManimScroll>
);
}3. Build
next buildThe plugin:
- Scans your source files for
<ManimScroll>components - Extracts props and children text
- Computes a hash for each unique animation
- Renders only new/changed animations (cached by hash)
- Outputs assets to
public/manim-assets/
Configuration
Combined Config (Recommended)
module.exports = withManimScroll({
// Next.js config
reactStrictMode: true,
// Manim Scroll config
manimScroll: {
pythonPath: "python3",
quality: "h",
fps: 30,
resolution: "1920x1080",
verbose: true,
},
});Separate Configs
const nextConfig = {
reactStrictMode: true,
};
module.exports = withManimScroll(nextConfig, {
pythonPath: "python3",
quality: "h",
});Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| pythonPath | string | "python3" | Path to Python executable |
| cliPath | string | Built-in | Path to render CLI script |
| templatesDir | string | Built-in | Path to scene templates |
| quality | string | "h" | Manim quality preset (l, m, h, k) |
| fps | number | 30 | Frames per second |
| resolution | string | "1920x1080" | Output resolution (WIDTHxHEIGHT) |
| format | string | "both" | Output format (frames, video, both) |
| concurrency | number | CPU count - 1 | Max parallel renders |
| include | string[] | ["**/*.tsx", "**/*.jsx"] | Glob patterns to scan |
| exclude | string[] | ["node_modules/**", ".next/**"] | Glob patterns to exclude |
| cleanOrphans | boolean | true | Remove unused cached assets |
| verbose | boolean | false | Enable verbose logging |
Exports
Main Export
withManimScroll(config, manimConfig?)- Next.js config wrapper
Types
ManimScrollConfig- Plugin configuration typeNextConfigWithManimScroll- Extended Next.js config type
Utilities (Advanced)
import {
extractAnimations,
renderAnimations,
computePropsHash,
isCached,
getCacheEntry,
getAnimationsToRender,
writeCacheManifest,
readCacheManifest,
cleanOrphanedCache,
processManimScroll,
} from "@mihirsarya/manim-scroll-next";How It Works
1. Extraction
The plugin uses Babel to parse your source files and extract <ManimScroll> component usages:
<ManimScroll scene="TextScene" fontSize={72} color="#fff">
Hello World
</ManimScroll>Becomes:
{
id: "app/page.tsx:ManimScroll:1",
scene: "TextScene",
props: { text: "Hello World", fontSize: 72, color: "#fff" }
}2. Caching
Each animation is hashed based on scene + props. The cache manifest at public/manim-assets/cache-manifest.json maps hashes to rendered asset directories:
{
"version": 1,
"animations": {
"abc123...": "/manim-assets/abc123.../manifest.json"
}
}3. Rendering
New animations are rendered using the bundled Python CLI:
python render/cli.py \
--scene-file render/templates/text_scene.py \
--scene-name TextScene \
--props '{"text": "Hello World", "fontSize": 72}' \
--output-dir public/manim-assets/abc123...4. Asset Structure
public/manim-assets/
├── cache-manifest.json
├── abc123.../
│ ├── manifest.json
│ ├── media/
│ │ ├── videos/...
│ │ └── images/...
└── def456.../
└── ...Development Mode
In dev mode (next dev), the plugin:
- Creates an empty cache manifest immediately to prevent 404s
- Processes animations asynchronously in the background
- Retries manifest resolution if animations are still rendering
Custom Build Scripts
For advanced workflows, use the exported utilities:
import { extractAnimations, renderAnimations } from "@mihirsarya/manim-scroll-next";
async function customBuild() {
const animations = await extractAnimations({
rootDir: process.cwd(),
include: ["src/**/*.tsx"],
});
const results = await renderAnimations(animations, "./public", {
pythonPath: "python3",
quality: "h",
});
console.log(`Rendered ${results.filter(r => r.success).length} animations`);
}Troubleshooting
Manim not found
Ensure Manim is installed and accessible:
python3 -c "import manim; print(manim.__version__)"Animations not updating
The cache is based on props hash. To force re-render:
- Delete
public/manim-assets/ - Or change a prop value
Slow builds
- Reduce
quality(use"l"or"m"for development) - Increase
concurrencyif you have more CPU cores - Use
format: "frames"to skip video encoding
License
MIT
