Skip to main content

Node.js

Motion Canvas builds on top of the Vite plugin system. To create a plugin thatruns on Node.js, you just create a Vite plugin and import it inyour vite.config.ts file. On top of that, @motion-canvas/vite-plugin provides a symbol that lets you define motion-canvas-specific options.

Let's start by creating a file for our plugin. This time we'll put it in theroot directory of our project because Vite plugins are not part of the runtimesource code.

We use the Vite configureServer hook to add a customendpoint. Meanwhile, the entryPoint option lets us specify the path to ourruntime plugin:

Project structure
                                
                                  
                                    
                                     project/
                                    
├── src/
│ ├── scenes/
│ │ └── example.tsx
│ ├── plugin.ts
│ └── project.ts
├── package.json
├── tsconfig.json
+ ├── myVitePlugin.ts
└── vite.config.ts
myVitePlugin.ts
                            
                              
                                import
                                
                                {
                                Plugin
                                ,
                                
                                PLUGIN_OPTIONS
                                }
                                
                                from
                                
                                '@motion-canvas/vite-plugin'
                                ;
                                
                                

export default function myVitePlugin ( ) : Plugin {
return {
name : 'vite-plugin-motion-canvas-example' ,

// extend the dev server using Vite plugin hooks:
configureServer ( server ) {
server . middlewares . use ( '/my-plugin' , ( req , res ) => {
res . end ( 'Hello from my plugin!' ) ;
} ) ;
} ,

// extend Motion Canvas:
[ PLUGIN_OPTIONS ] : {
entryPoint : './plugin.ts' ,
} ,
} ;
}

Here's how we would import such plugin in our vite.config.ts file:

vite.config.ts
                            
                              
                                import
                                
                                {
                                defineConfig
                                }
                                
                                from
                                
                                'vite'
                                ;
                                
                                
import motionCanvas from '@motion-canvas/vite-plugin' ;
import myVitePlugin from './myVitePlugin' ;

export default defineConfig ( {
plugins : [
motionCanvas ( ) ,
myVitePlugin ( ) ,
] ,
} ) ;

Also, since we defined the entry point in the Node.js plugin, we no longer needto import the runtime plugin in our project file:

src/project.ts
                            
                              
                                
                                 import {makeProject} from '@motion-canvas/core';
                                
- import myPlugin from './plugin';
import example from './scenes/example?scene';

export default makeProject({
scenes: [example],
- plugins: [myPlugin()],
});
tip

Notice that we defined the entry point as './plugin.ts' . Because it's arelative path, it will be resolved relative to the project file. Once you turnyour plugin into a separate package, you can use a package name instead.

You can verify that the plugin is working by running the project and visiting http://localhost:9000/my-plugin .

Passing options to Runtime

A Node.js plugin has the ability to pass options to the runtime plugin. We cando that using the runtimeConfig property:

myVitePlugin.ts
                            
                              
                                import
                                
                                {
                                Plugin
                                ,
                                
                                PLUGIN_OPTIONS
                                }
                                
                                from
                                
                                '@motion-canvas/vite-plugin'
                                ;
                                
                                

export default function myVitePlugin ( ) : Plugin {
return {
name : 'vite-plugin-motion-canvas-example' ,
// ...
[ PLUGIN_OPTIONS ] : {
entryPoint : './plugin.ts' ,
runtimeConfig : ( ) => ( {
foo : 'bar' ,
} ) ,
} ,
} ;
}

We can then update the runtime plugin to receive these options:

src/plugin.ts
                            
                              
                                import
                                
                                {
                                makePlugin
                                }
                                
                                from
                                
                                '@motion-canvas/core'
                                ;
                                
                                

interface MyPluginOptions {
foo : string ;
}

export default makePlugin ( ( options ? : MyPluginOptions ) => {
console . log ( options ?. foo ) ; // 'bar'

return {
name : 'motion-canvas-plugin-example' ,
player ( player ) {
player . onRecalculated . subscribe ( ( ) => {
player . requestReset ( ) ;
player . togglePlayback ( true ) ;
} ) ;
} ,
} ;
} ) ;