Contributing
Thank you for your interest in contributing to MotionScript! This guide covers how to set up the development environment, understand the repo structure, and submit changes.
Repository structure
motion-script/
├── packages/
│ ├── core/ # @motion-script/core — the animation engine
│ ├── player/ # @motion-script/player — browser renderer
│ ├── react/ # @motion-script/react — React bindings
│ ├── docs/ # This documentation site
│ ├── my-video/ # Example project / testbed
│ └── components/
│ ├── latex/ # @motion-script/latex
│ ├── code/ # @motion-script/code
│ └── three/ # @motion-script/three
The monorepo uses pnpm workspaces and Turborepo.
Getting started
Prerequisites
- Node.js 18 or later
- pnpm 9 or later
npm install -g pnpm
Install dependencies
pnpm install
Build core
The player and docs depend on the prebuilt @motion-script/core dist. Build it first:
pnpm --filter @motion-script/core build
Start the docs site
pnpm --filter @motion-script/docs start
Start the example project
pnpm --filter @motion-script/player dev
Development workflow
Making changes to core
After editing packages/core/src, rebuild the package:
pnpm --filter @motion-script/core build
Or run the watch mode:
pnpm --filter @motion-script/core dev
Player dependency
The player Vite config aliases @motion-script/player to its prebuilt dist. After rebuilding core, restart the dev server to pick up changes.
Running tests
pnpm test
# or run tests for a specific package
pnpm --filter @motion-script/core test
Type checking
pnpm typecheck
Submitting a pull request
- Fork the repository on GitHub.
- Create a branch from
main:git checkout -b feat/my-feature. - Make your changes and ensure tests pass:
pnpm test. - Commit with a descriptive message.
- Push and open a pull request against
main.
What makes a good PR
- Focused changes — one concern per PR
- Tests for new behaviour
- Updated docs if you added or changed a public API
- No breaking changes without a discussion issue first
Adding a new node
- Create
packages/core/src/nodes/<category>/<name>-node.ts. - Extend
ShapeNode<YourProps>and implementrenderSelf(draw: RenderContext). - Export from
packages/core/src/nodes/index.ts. - Add a page under
packages/docs/docs/nodes/.
Adding a new image filter
- Create
packages/core/src/attributes/shape/filters/implementations/<name>.ts. - Implement the
FilterRegistry.register<YourFilter>(...)call with alerpandequalsfunction. - Add the type to
MXinpackages/core/src/attributes/shape/filters/chain.ts. - Add a page under
packages/docs/docs/image-filters/.
Adding a new node effect
- Create
packages/core/src/attributes/shape/effects/implementations/<name>.ts. - Register it with the effect registry and add to
FXinpackages/core/src/attributes/shape/effects/chain.ts. - Add a page under
packages/docs/docs/node-effects/.
Code style
- TypeScript strict mode throughout
- No comments unless the WHY is non-obvious
- Prefer editing existing files over creating new ones
- Run
pnpm lintbefore committing