Describe the Feature / Proposal
Currently, development.md (recommends following Conventional Commits but only links to the generic specification, it does not define which types, scopes, or structure rules apply specifically to Manim.
I propose adding a dedicated Commit Message Format page to the contributing documentation, and a commitizen pre-commit hook to validate commit messages locally before they are recorded.
Proposed Changes
1. New documentation page: docs/source/contributing/commits.md
A detailed guide that customizes the Conventional Commits spec for Manim's architecture:
- Allowed types:
build | ci | docs | feat | fix | perf | refactor | test, each with Manim-specific descriptions and examples.
- Allowed scopes:
mobject | scene | animation | renderer | camera | cli | config | utils | docs | tests, mapped to their source folders (e.g. mobject → manim/mobject/, config → manim/_config/).
- Message structure: header (
<type>(<scope>): <summary>), mandatory body (≥ 20 chars, except for docs type), optional footer for BREAKING CHANGE: / DEPRECATED: / issue references.
- Revert format:
revert: <original header> with SHA and reason in the body.
- Concrete examples: simple fix, feature with body, docs change, refactor, breaking change, and revert.
Click to expand the proposed draft (commits.md)
Commit Message Format
We have precise rules over how our Git commit messages must be formatted.
This format leads to easier to read commit history and enables automated changelog generation and semantic versioning.
Each commit message consists of a header, a body, and a footer.
<header>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
The header is mandatory and must conform to the Commit Message Header format.
The body is mandatory for all commits except for those of type docs.
When the body is present it must be at least 20 characters long and must conform to the Commit Message Body format.
The footer is optional. The Commit Message Footer format describes what the footer is used for and the structure it must have.
Commit Message Header
<type>(<scope>): <short summary>
│ │ │
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─⫸ Commit Scope: mobject|scene|animation|renderer|camera|cli|config|utils|docs|tests
│
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|test
The <type> and <summary> fields are mandatory, the (<scope>) field is optional.
Summary
Use the summary field to provide a succinct description of the change:
- Use the imperative, present tense: "change" not "changed" nor "changes"
- Don't capitalize the first letter
- No period (.) at the end
Type
Must be one of the following:
| Type |
Description |
Manim Examples |
| build |
Changes that affect the build system or external dependencies |
pyproject.toml, dependency upgrades, hatchling build config |
| ci |
Changes to our CI configuration files and scripts |
GitHub Actions workflows, pre-commit configuration |
| docs |
Documentation-only changes |
Sphinx .rst guides, Markdown .md files, inline docstrings |
| feat |
A new feature |
A new geometric mobject, a new animation class, or a new CLI flag |
| fix |
A bug fix |
Fixing rendering crashes, coordinate misalignments, or type errors |
| perf |
A code change that improves performance |
Optimizing shader compilation, caching, or numpy operations |
| refactor |
A code change that neither fixes a bug nor adds a feature |
Decomposing large files, extracting helper classes |
| test |
Adding missing tests or correcting existing tests |
pytest modules, graphical output assertions, video regression tests |
Scope
The scope should be the name of the module or architectural area affected by the change.
| Scope |
Folder |
Description |
mobject |
manim/mobject/ |
Mathematical Objects: shapes, text, images, graphs |
scene |
manim/scene/ |
Scenes: animation lifecycle, construct(), timing |
animation |
manim/animation/ |
Animations: drawing effects, transformations, speed modifiers |
renderer |
manim/renderer/ |
Renderers: render loop, frame generation, Cairo/OpenGL backends |
camera |
manim/camera/ |
Cameras: frame dimensions, zoom, panning, 3D perspectives |
cli |
manim/cli/ |
CLI: argument parsing, subcommands, output formats |
config |
manim/_config/ |
Configuration: global settings, manim.cfg, ManimConfig |
utils |
manim/utils/ |
Utilities: colors, vectors, rate curves, Sphinx extensions |
docs |
docs/ |
Documentation: Sphinx source, tutorials, translations |
tests |
tests/ |
Test Suite: unit tests, graphical/video regression tests |
Exceptions:
packaging: changes to Python packaging layout (e.g. pyproject.toml metadata, __init__.py exports)
changelog: updating release notes
- none/empty: cross-cutting changes across multiple scopes
Commit Message Body
Use the imperative, present tense: "fix" not "fixed" nor "fixes".
Explain the motivation for the change. Include a comparison of previous vs. new behavior when it helps illustrate impact.
Commit Message Footer
The footer can contain information about breaking changes and deprecations, and references to GitHub issues or PRs.
BREAKING CHANGE: <breaking change summary>
<BLANK LINE>
<breaking change description + migration instructions>
<BLANK LINE>
Fixes #<issue number>
Revert Commits
If the commit reverts a previous commit, begin with revert: , followed by the header of the reverted commit.
The body should contain:
This reverts commit <SHA>.
- A clear description of the reason for reverting.
Examples
Simple fix:
fix(mobject): resolve vectorized fill opacity bug
Feature with body:
feat(animation): add staggered fade-in animation for submobjects
The existing FadeIn animation applies the effect to the entire mobject at once.
This new StaggeredFadeIn class applies a cascading delay to each submobject,
which is useful for animating grouped elements like matrix entries or graph nodes.
Closes #2145
Documentation change (body not required):
docs(config): add examples for ManimConfig programmatic usage
Breaking change:
feat(renderer): remove deprecated Cairo-only rendering path
BREAKING CHANGE: The `use_cairo_renderer` config flag has been removed.
All scenes now render through the unified pipeline. Users who relied on
Cairo-specific behavior should migrate to the OpenGL renderer or use
the compatibility shim documented in the migration guide.
Closes #1892
Revert:
revert: fix(mobject): resolve vectorized fill opacity bug
This reverts commit 21cf999abc123.
The original fix introduced a regression in 3D mobject rendering where
transparency values were incorrectly inherited by child submobjects.
2. Pre-commit hook: commitizen validation (.pre-commit-config.yaml)
Added commit-msg to default_stages and a new hook using commitizen-tools/commitizen v3.27.0 at the commit-msg stage:
-default_stages: [pre-commit, pre-push]
+default_stages: [pre-commit, pre-push, commit-msg]
+ - repo: https://github.com/commitizen-tools/commitizen
+ rev: v3.27.0
+ hooks:
+ - id: commitizen
+ stages: [commit-msg]
3. Commitizen configuration (pyproject.toml)
Added a [tool.commitizen] section with a regex pattern that strictly validates the allowed types and scopes:
+[tool.commitizen]
+name = "cz_conventional_commits"
+pattern = "^(?P<type>build|ci|docs|feat|fix|perf|refactor|test)..."
+schema_pattern = "^(build|ci|docs|feat|fix|perf|refactor|test)..."
+schema = "Example: fix(mobject): resolve vectorized fill opacity bug"
Why This Matters: Real Before & After Examples
To illustrate the impact, here is how some recent commits in the repository would look under the proposed guidelines:
| Original Commit |
With Proposed Format |
What Changed |
Fixed inconsistent stroke width
scaling for text in compound
objects (#4694)
|
fix(mobject): resolve inconsistent
stroke width scaling for text in
compound objects
Ensure stroke width scales
consistently for text inside compound
mobjects when the parent mobject
is resized.
Closes #4694
|
Added fix type and mobject scope. Changed past tense → present tense. Moved issue reference to footer. Added body with motivation. |
Implement Mobject.always (#4594)
|
feat(mobject): implement always method
Add the always method to easily
register updater functions that
continuously run on the mobject.
Closes #4594
|
Added feat type and mobject scope. Lowercase summary. Added body explaining what the feature does. |
Replace scipy.special.comb
with math.comb (#4598)
|
refactor(utils): replace
scipy.special.comb with math.comb
|
Added refactor type and utils scope (file: manim/utils/simple_functions.py). Lowercase, no PR number. |
Update TinyTeX Windows/macOS
installation in `ci.yml` to fix
failing pipelines (#4679)
|
ci: update TinyTeX installation
on Windows and macOS
|
Changed to ci type (no scope needed, it's a workflow file). Clean, concise single-line header. |
docs: improve TransformFromCopy
docstring (#4597)
|
docs(animation): improve
TransformFromCopy docstring
|
Added animation scope (file is in manim/animation/). Removed PR number. No body needed for docs. |
Pattern: Most commits gain a clear type + scope, and get a lowercase imperative summary. Non-trivial fixes/features also get an explanatory body.
Benefits
- Better onboarding: New contributors see exactly which
type and scope to use instead of guessing from a generic spec.
- Immediate local feedback: The commitizen hook rejects non-compliant messages at
commit-msg stage, catching errors before CI.
- Consistent history: Standardized format enables future automated changelog generation and semantic versioning.
If the proposal is accepted, I can submit a Pull Request that:
- Adds
docs/source/contributing/commits.md
- Updates the reference in
development.md
- Includes the
.pre-commit-config.yaml and pyproject.toml changes shown above
Describe the Feature / Proposal
Currently,
development.md(recommends following Conventional Commits but only links to the generic specification, it does not define which types, scopes, or structure rules apply specifically to Manim.I propose adding a dedicated Commit Message Format page to the contributing documentation, and a commitizen pre-commit hook to validate commit messages locally before they are recorded.
Proposed Changes
1. New documentation page:
docs/source/contributing/commits.mdA detailed guide that customizes the Conventional Commits spec for Manim's architecture:
build | ci | docs | feat | fix | perf | refactor | test, each with Manim-specific descriptions and examples.mobject | scene | animation | renderer | camera | cli | config | utils | docs | tests, mapped to their source folders (e.g.mobject→manim/mobject/,config→manim/_config/).<type>(<scope>): <summary>), mandatory body (≥ 20 chars, except fordocstype), optional footer forBREAKING CHANGE:/DEPRECATED:/ issue references.revert: <original header>with SHA and reason in the body.Click to expand the proposed draft (commits.md)
Commit Message Format
We have precise rules over how our Git commit messages must be formatted.
This format leads to easier to read commit history and enables automated changelog generation and semantic versioning.
Each commit message consists of a header, a body, and a footer.
The
headeris mandatory and must conform to the Commit Message Header format.The
bodyis mandatory for all commits except for those of typedocs.When the body is present it must be at least 20 characters long and must conform to the Commit Message Body format.
The
footeris optional. The Commit Message Footer format describes what the footer is used for and the structure it must have.Commit Message Header
The
<type>and<summary>fields are mandatory, the(<scope>)field is optional.Summary
Use the summary field to provide a succinct description of the change:
Type
Must be one of the following:
pyproject.toml, dependency upgrades,hatchlingbuild configpre-commitconfiguration.rstguides, Markdown.mdfiles, inline docstringsScope
The scope should be the name of the module or architectural area affected by the change.
mobjectmanim/mobject/scenemanim/scene/construct(), timinganimationmanim/animation/renderermanim/renderer/cameramanim/camera/climanim/cli/configmanim/_config/manim.cfg,ManimConfigutilsmanim/utils/docsdocs/teststests/Exceptions:
packaging: changes to Python packaging layout (e.g.pyproject.tomlmetadata,__init__.pyexports)changelog: updating release notesCommit Message Body
Use the imperative, present tense: "fix" not "fixed" nor "fixes".
Explain the motivation for the change. Include a comparison of previous vs. new behavior when it helps illustrate impact.
Commit Message Footer
The footer can contain information about breaking changes and deprecations, and references to GitHub issues or PRs.
Revert Commits
If the commit reverts a previous commit, begin with
revert:, followed by the header of the reverted commit.The body should contain:
This reverts commit <SHA>.Examples
Simple fix:
Feature with body:
Documentation change (body not required):
Breaking change:
Revert:
2. Pre-commit hook: commitizen validation (
.pre-commit-config.yaml)Added
commit-msgtodefault_stagesand a new hook usingcommitizen-tools/commitizenv3.27.0 at thecommit-msgstage:3. Commitizen configuration (
pyproject.toml)Added a
[tool.commitizen]section with a regex pattern that strictly validates the allowed types and scopes:Why This Matters: Real Before & After Examples
To illustrate the impact, here is how some recent commits in the repository would look under the proposed guidelines:
fixtype andmobjectscope. Changed past tense → present tense. Moved issue reference to footer. Added body with motivation.feattype andmobjectscope. Lowercase summary. Added body explaining what the feature does.refactortype andutilsscope (file:manim/utils/simple_functions.py). Lowercase, no PR number.citype (no scope needed, it's a workflow file). Clean, concise single-line header.animationscope (file is inmanim/animation/). Removed PR number. No body needed fordocs.Benefits
typeandscopeto use instead of guessing from a generic spec.commit-msgstage, catching errors before CI.If the proposal is accepted, I can submit a Pull Request that:
docs/source/contributing/commits.mddevelopment.md.pre-commit-config.yamlandpyproject.tomlchanges shown above