Skip to main content


Runtime plugins allow you to extend the runtime components like scenes and the player.

Let's start by creating the entry point - a simple file that exports our plugin. For now, we'll put that file in the src directory of our Motion Canvas project. If you find yourself reusing the plugin across multiple projects, you can put it in a separate package.

To define the plugin, we pass a configuration object to the makePlugin helper function and export the result. name is the only required property. player is an optional hook that will receive the Player instance right after it's created. Take a look at the Plugin interface for the full list of available hooks.

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

export default makePlugin({
name: 'motion-canvas-plugin-example',
player(player) {
player.onRecalculated.subscribe(() => {

In this example we subscribe to the onRecalculated event to play the animation from the beginning whenever this event occurs. Recalculation happens when we edit the animation either in the editor or in the code.

Now we can import the plugin in our project file. Note that makePlugin returns a function that we need to call to create an actual plugin object (This can come in handy when developing a Node.js plugin):

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

export default makeProject({
scenes: [example],
plugins: [myPlugin()],
// ^^ we need to call the function

That's it! Now we can run the project and see our plugin in action. Check out the Plugin interface for the full list of available hooks.