M

motion-canvas

Verified

by davila7 · Updated Apr 16, 2026

claude-opus-4-6
1.2Kin7.1Kout
$0.624m 31s

Complete production-ready guide for Motion Canvas with ESM/CommonJS workarounds, full setup templates, and troubleshooting for programmatic video creation using TypeScript

motion-canvastypescriptvideoanimationvitefrontend

See It In Action

1 turns·claude
The project codebase is in your current working directory. Explore the files to understand the code before making changes. my motion canvas teaser is busted and marketing needs it today — can you fix it so it runs and hand me the finished project plus a quick note on what was wrong

Let me install dependencies and try to build to see the actual errors:

Good, I can see the errors. Let me check the actual exports from the installed packages:

Good — the jsxImportSource in tsconfig is actually correct since jsx-runtime lives under lib/. Now let me check the deep imports used in the scene file work properly in Vite context:

Now I have the full picture. The critical error is in vite.config.js — the vite plugin is a CJS package and the default import yields the module.exports object, not the function. Let me fix it:

The vite-plugin function call now works, but it requires @motion-canvas/ui as a peer dependency. Let me install that:

Build passes. Let me also try vite dev briefly to confirm it actually serves:

Dev server starts fine. Now let me update the package.json to include the missing dependency:

Everything is building and running. Let me verify the final state of all files:

The project is fixed and building clean. Here's a summary of the two bugs:


What was wrong

Bug 1 – vite.config.js: CJS ↔ ESM default-export mismatch (the build-breaker)

@motion-canvas/vite-plugin ships as CommonJS. When your ESM vite config does import motionCanvas from '...', the default import resolves to the entire module.exports object, not the plugin factory function sitting at module.exports.default. So motionCanvas(...) blows up with TypeError: motionCanvas is not a function.

Fix: Unwrap the double-default:

import motionCanvasPlugin from '@motion-canvas/vite-plugin';
const motionCanvas = motionCanvasPlugin.default ?? motionCanvasPlugin;

Bug 2 – package.json: missing @motion-canvas/ui peer dependency

The vite plugin internally require('@motion-canvas/ui') to serve the editor UI. That package wasn't listed in devDependencies, so the plugin crashed at startup with Cannot find module '@motion-canvas/ui'.

Fix: Added @motion-canvas/ui to devDependencies.


No changes were needed in tsconfig.json, project.ts, or teaser.tsx — the scene code, deep import paths, and JSX config were all correct. After the two fixes above, npm run dev serves the Motion Canvas editor on localhost:9000 and npm run build produces a clean production bundle.

Claude Sonnet 4.6

External Tools

ToolType
nodebinary
npmbinary

Permissions

ScopeDescription
filesystem:read
filesystem:write
process:spawn

SKILL.md

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 createRequire workaround 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:

  1. Verify vite.config.js has the correct workaround
  2. Check project path points to correct file: './src/project.ts'
  3. Ensure scene imports use ?scene suffix: import example from './scenes/example?scene';

Build fails with TypeScript errors

Solution:

  1. Verify tsconfig.json includes all required options (see Step 6)
  2. Check jsxImportSource is set to @motion-canvas/2d/lib
  3. Ensure all dependencies are installed

How to use

Read individual rule files for detailed explanations and code examples:

Core Animation Concepts

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

  1. Always use the createRequire workaround - Don't try standard ESM imports for the Vite plugin
  2. Use vite.config.js not .ts - Avoids additional compilation complexity
  3. Include all dependencies - Don't forget @motion-canvas/ui
  4. Use generator functions - All scene animations should use function* and yield* syntax
  5. Leverage signals - Create reactive dependencies between properties
  6. Think in durations - Specify animation duration in seconds as the second parameter
  7. Use refs for control - Create references to nodes for precise animation control
  8. Preview frequently - Take advantage of the real-time editor for instant feedback
  9. Organize scenes - Break complex animations into multiple scenes
  10. Type everything - Use TypeScript for better IDE support and fewer errors

Common Pitfalls to Avoid

  1. ❌ Forgetting "type": "module" in package.json
  2. ❌ Using standard import for @motion-canvas/vite-plugin
  3. ❌ Not installing @motion-canvas/ui
  4. ❌ Missing esModuleInterop in tsconfig.json
  5. ❌ Using vite.config.ts instead of vite.config.js
  6. ❌ Forgetting ?scene suffix in scene imports

Resources

FAQ

What does motion-canvas do?

Complete production-ready guide for Motion Canvas with ESM/CommonJS workarounds, full setup templates, and troubleshooting for programmatic video creation using TypeScript

When should I use motion-canvas?

Use it when you need a repeatable workflow that produces source code, text report, code diff.

What does motion-canvas output?

In the evaluated run it produced source code, text report, code diff.

How do I install or invoke motion-canvas?

npx skills add https://github.com/davila7/claude-code-templates --skill motion-canvas

Which agents does motion-canvas support?

Claude Code

What tools, channels, or permissions does motion-canvas need?

It uses node, npm; channels commonly include code, text, diff, file; permissions include filesystem:read, filesystem:write, process:spawn.

Is motion-canvas safe to install?

Static analysis marked this skill as medium risk; review side effects and permissions before enabling it.

How is motion-canvas different from an MCP or plugin?

A skill packages instructions and workflow conventions; tools, MCP servers, and plugins are dependencies the skill may call during execution.

Does motion-canvas outperform not using a skill?

About motion-canvas

When to use motion-canvas

You need to scaffold or fix a Motion Canvas project using TypeScript and Vite. You are troubleshooting Motion Canvas setup errors related to the Vite plugin, ESM/CommonJS interop, or scene imports. You want the agent to create or modify animation scene code and project configuration for programmatic video generation.

When motion-canvas is not the right choice

You only need general video editing or rendering in non-Motion-Canvas tools. You want browser automation, cloud rendering, or third-party publishing workflows rather than local project setup and code authoring.

What it produces

Produces source code, text report and code diff.

Install

npx skills add https://github.com/davila7/claude-code-templates --skill motion-canvas

Invoke: Ask Claude Code to use motion-canvas for the task.