motion-canvas
Provides project templates and troubleshooting for creating programmatic videos using Motion Canvas and TypeScript.
Install
mkdir -p .claude/skills/motion-canvas && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/866" && unzip -o skill.zip -d .claude/skills/motion-canvas && rm skill.zipInstalls to .claude/skills/motion-canvas
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Complete production-ready guide for Motion Canvas with ESM/CommonJS workarounds, full setup templates, and troubleshooting for programmatic video creation using TypeScriptKey capabilities
- →Apply createRequire workaround for ESM compatibility
- →Initialize reactive signals with state management
- →Orchestrate animations using generator functions
- →Configure Vite build settings for production exports
How it works
It maps code definitions to Canvas API calls using generator functions to track timeline frames, while injecting custom node resolution logic to bypass CJS/ESM module loading failures.
Inputs & outputs
When to use motion-canvas
- →Set up a new Motion Canvas project
- →Create programmatic animations in TypeScript
- →Debug ESM import issues in animations
- →Synchronize animations with voice-overs
About this skill
Motion Canvas - Production-Ready Video Creation with TypeScript
Complete production-ready skill for creating programmatic videos using Motion Canvas, including critical ESM/CommonJS workarounds, full configuration templates, and comprehensive troubleshooting.
⚠️ CRITICAL: ESM/CommonJS Interoperability Issue
IMPORTANT: The @motion-canvas/vite-plugin package is distributed as CommonJS, which causes import errors in modern ESM projects. The standard import motionCanvas from '@motion-canvas/vite-plugin' WILL NOT WORK.
You MUST use the createRequire workaround documented in the Setup section below.
When to use
Use this skill whenever you are dealing with Motion Canvas code to obtain domain-specific knowledge about:
- Creating animated videos using TypeScript and generator functions
- Building animations with signals and reactive values
- Working with vector graphics and Canvas API
- Synchronizing animations with voice-overs and audio
- Using the real-time preview editor for instant feedback
- Implementing procedural animations with flow control
- Creating informative visualizations and diagrams
- Animating text, shapes, and custom components
- Setting up Motion Canvas projects from scratch with correct configuration
- Troubleshooting common setup and build errors
Core Concepts
Motion Canvas allows you to create videos using:
- Generator Functions: Describe animations using JavaScript generators with
yield*syntax - Signals: Reactive values that automatically update dependent properties
- Real-time Preview: Live editor with instant preview powered by Vite
- TypeScript-First: Write animations in TypeScript with full IDE support
- Canvas API: Leverage 2D Canvas for high-performance vector rendering
- Audio Synchronization: Sync animations precisely with voice-overs
Complete Setup Guide
Step 1: Initialize Project
# Create project directory
mkdir my-motion-canvas-project
cd my-motion-canvas-project
# Initialize package.json
npm init -y
Step 2: Configure package.json for ESM
CRITICAL: Add "type": "module" to enable ESM imports.
{
"name": "my-motion-canvas-project",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
}
}
Step 3: Install ALL Required Dependencies
CRITICAL: Must include @motion-canvas/ui - the plugin will fail without it.
npm install --save-dev @motion-canvas/core @motion-canvas/2d @motion-canvas/vite-plugin @motion-canvas/ui vite typescript
Step 4: Create Project Structure
my-motion-canvas-project/
├── package.json # "type": "module" required
├── vite.config.js # Use .js NOT .ts (see Step 5)
├── tsconfig.json # TypeScript configuration
├── index.html # HTML entry point
└── src/
├── project.ts # Project configuration with scenes
└── scenes/
└── example.tsx # Animation scene
Step 5: Create vite.config.js with ESM/CommonJS Workaround
CRITICAL: Use vite.config.js (NOT .ts) with the createRequire workaround.
File: vite.config.js
import {defineConfig} from 'vite';
import {createRequire} from 'module';
// WORKAROUND: @motion-canvas/vite-plugin is CommonJS, must use require
const require = createRequire(import.meta.url);
const motionCanvasModule = require('@motion-canvas/vite-plugin');
const motionCanvas = motionCanvasModule.default || motionCanvasModule;
export default defineConfig({
plugins: [
motionCanvas({
project: './src/project.ts',
}),
],
});
Why .js instead of .ts?
- Vite config runs before TypeScript compilation
- The
createRequireworkaround works reliably in plain JavaScript - Avoids additional type resolution complexity
Step 6: Create tsconfig.json
CRITICAL: Include esModuleInterop and allowSyntheticDefaultImports.
File: tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ES2020",
"lib": ["ES2020", "DOM"],
"jsx": "react-jsx",
"jsxImportSource": "@motion-canvas/2d/lib",
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
Step 7: Create index.html
File: index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Motion Canvas Project</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/project.ts"></script>
</body>
</html>
Step 8: Create src/project.ts
File: src/project.ts
import {makeProject} from '@motion-canvas/core';
import example from './scenes/example?scene';
export default makeProject({
scenes: [example],
});
Step 9: Create First Animation Scene
File: src/scenes/example.tsx
import {makeScene2D} from '@motion-canvas/2d/lib/scenes';
import {Circle} from '@motion-canvas/2d/lib/components';
import {createRef} from '@motion-canvas/core/lib/utils';
import {all} from '@motion-canvas/core/lib/flow';
export default makeScene2D(function* (view) {
const circleRef = createRef<Circle>();
view.add(
<Circle
ref={circleRef}
size={70}
fill="#e13238"
/>,
);
// Animate circle size and position
yield* circleRef().size(140, 1);
yield* circleRef().position.x(300, 1);
yield* circleRef().fill('#e6a700', 1);
// Parallel animations
yield* all(
circleRef().scale(1.5, 0.5),
circleRef().rotation(360, 1)
);
});
Step 10: Run Development Server
npm run dev
Open browser at http://localhost:5173 to see the Motion Canvas editor.
Troubleshooting
Error: TypeError: motionCanvas is not a function
Cause: ESM/CommonJS interoperability issue with @motion-canvas/vite-plugin
Solution: Use the createRequire workaround in vite.config.js (see Step 5)
// ❌ WRONG - Will not work
import motionCanvas from '@motion-canvas/vite-plugin';
// ✅ CORRECT - Use createRequire
import {createRequire} from 'module';
const require = createRequire(import.meta.url);
const motionCanvasModule = require('@motion-canvas/vite-plugin');
const motionCanvas = motionCanvasModule.default || motionCanvasModule;
Error: Cannot find module '@motion-canvas/ui'
Cause: Missing required dependency
Solution: Install the UI package:
npm install --save-dev @motion-canvas/ui
Error: Property 'default' does not exist on type ...
Cause: TypeScript configuration missing ESM interop settings
Solution: Add to tsconfig.json:
{
"compilerOptions": {
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
}
}
Warning: The CJS build of Vite's Node API is deprecated
Status: This is a known warning and can be safely ignored. It appears because @motion-canvas/vite-plugin is CommonJS. The workaround ensures functionality despite the warning.
Error: Failed to resolve import "*.tsx?scene"
Cause: Vite plugin not properly loaded or configured
Solution:
- Verify
vite.config.jshas the correct workaround - Check
projectpath points to correct file:'./src/project.ts' - Ensure scene imports use
?scenesuffix:import example from './scenes/example?scene';
Build fails with TypeScript errors
Solution:
- Verify
tsconfig.jsonincludes all required options (see Step 6) - Check
jsxImportSourceis set to@motion-canvas/2d/lib - Ensure all dependencies are installed
How to use
Read individual rule files for detailed explanations and code examples:
Core Animation Concepts
- references/generators.md - Generator functions for describing animations
- references/signals.md - Reactive signals for dynamic properties and dependencies
- references/animations.md - Tweening properties and creating smooth animations
For additional topics like scenes, shapes, text rendering, audio synchronization, and advanced features, refer to the comprehensive Motion Canvas official documentation.
Complete Working Example
This is a complete, tested project structure that works out of the box:
my-motion-canvas-project/
├── package.json
│ {
│ "name": "my-motion-canvas-project",
│ "type": "module",
│ "scripts": {
│ "dev": "vite",
│ "build": "vite build"
│ },
│ "devDependencies": {
│ "@motion-canvas/core": "^3.0.0",
│ "@motion-canvas/2d": "^3.0.0",
│ "@motion-canvas/vite-plugin": "^3.0.0",
│ "@motion-canvas/ui": "^3.0.0",
│ "vite": "^5.0.0",
│ "typescript": "^5.0.0"
│ }
│ }
│
├── vite.config.js (with createRequire workaround)
├── tsconfig.json (with esModuleInterop)
├── index.html
└── src/
├── project.ts (makeProject with scenes array)
└── scenes/
└── example.tsx (makeScene2D with animations)
Best Practices
- Always use the createRequire workaround - Don't try standard ESM imports for the Vite plugin
- Use vite.config.js not .ts - Avoids additional compilation complexity
- Include all dependencies - Don't forget
@motion-canvas/ui - Use generator functions - All scene animations should use
function*andyield*syntax - Leverage signals - Create reactive dependencies between properties
- Think in durations - Specify animation duration in seconds as the second parameter
- Use refs for control - Create references to nodes for precise animation control
- Preview frequently - Take advantage of the real-time editor for instan
Content truncated.
When not to use it
- →Standard video editing tasks
- →Simple non-procedural web animations
Prerequisites
Limitations
- →Requires high technical knowledge of TypeScript
- →Heavy dependency on build-tool configuration
- →Steep learning curve for generator function logic
How it compares
It treats video creation as a software development project with strict typing and reactivity instead of relying on manual keyframe positioning in a GUI.
Compared to similar skills
motion-canvas side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| motion-canvas (this skill) | 58 | 6mo | Review | Advanced |
| json-render-remotion | 1 | 5mo | No flags | Intermediate |
| remotion-render | 0 | 1mo | Review | Advanced |
| drizzle | 238 | 2mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by davila7
View all by davila7 →You might also like
json-render-remotion
vercel-labs
Remotion renderer for json-render that turns JSON timeline specs into videos. Use when working with @json-render/remotion, building video compositions from JSON, creating video catalogs, or rendering AI-generated video timelines.
remotion-render
aiskillstore
Render videos from React/Remotion component code via inference.sh. Pass TSX code, get MP4. Supports all Remotion APIs: useCurrentFrame, useVideoConfig, spring, interpolate, AbsoluteFill, Sequence. Configurable resolution, FPS, duration, codec. Use for: programmatic video generation, animated graphic
drizzle
lobehub
Drizzle ORM schema and database guide. Use when working with database schemas (src/database/schemas/*), defining tables, creating migrations, or database model code. Triggers on Drizzle schema definition, database migrations, or ORM usage questions.
zustand
lobehub
Zustand state management guide. Use when working with store code (src/store/**), implementing actions, managing state, or creating slices. Triggers on Zustand store development, state management questions, or action implementation.
turborepo
vercel
Turborepo monorepo build system guidance. Triggers on: turbo.json, task pipelines, dependsOn, caching, remote cache, the "turbo" CLI, --filter, --affected, CI optimization, environment variables, internal packages, monorepo structure/best practices, and boundaries. Use when user: configures tasks/workflows/pipelines, creates packages, sets up monorepo, shares code between apps, runs changed/affected packages, debugs cache, or has apps/packages directories.
shadcn-ui-setup
maneeshanif
Install and configure Shadcn/ui component library with Radix UI primitives, Aceternity UI effects, set up components, and manage the component registry. Use when adding Shadcn/ui to a Next.js project or installing specific UI components for Phase 2.