For candidates interested in participating in the Google Summer of Code (GSoC), checkout Mesa’s GSoC guide.
As an open source project, Mesa welcomes contributions of many forms, and from beginners to experts. If you are curious or just want to see what is happening, we post our development session agendas and development session notes on Mesa discussions. We also have a threaded discussion forum on Matrix for casual conversation.
In no particular order, examples include:
- Code patches
- Bug reports and patch reviews
- New features
- Documentation improvements
- Tutorials
No contribution is too small. Although, contributions can be too big, so let's discuss via Matrix OR via an issue.
To submit a contribution
- For enhancements or new features, open an issue or discussion first and wait for maintainer approval before opening a PR.
- For clear bug fixes, a direct PR is generally acceptable (opening an issue first is still encouraged for larger or unclear bugs).
- Fork the Mesa repository.
- Clone your repository from Github to your machine.
- Create a new branch in your fork:
git checkout -b BRANCH_NAME - Run
git config pull.rebase true. This prevents messy merge commits when updating your branch on top of Mesa main branch. - Install an editable version with developer requirements locally:
pip install -e ".[dev]" - Edit the code. Save.
- Git add the new files and files with changes:
git add FILE_NAME - Git commit your changes with a meaningful message:
git commit -m "Fix issue X" - If implementing a new feature, include some documentation in docs folder.
- Make sure that your submission works with a few of the examples in the examples repository. If adding a new feature to mesa, please illustrate usage by implementing it in an example.
- Make sure that your submission passes the GH Actions build. See "Testing and Standards below" to be able to run these locally.
- Make sure that your code is formatted according to [the ruff] standard (you can do it via pre-commit).
- Push your changes to your fork on Github:
git push origin NAME_OF_BRANCH. - Create a pull request.
- Describe the change w/ ticket number(s) that the code fixes.
- Format your commit message as per Tim Pope's guideline.
That's fine! Here's a rough outline where you could start, depending on your experience:
You already know how to build Mesa models (if not skip below), and probably have found things Mesa can't do (elegantly). You want to improve that. Awesome!
First step is to install some proper tools, if you haven't already.
- A good IDE helps for code development, testing and formatting. PyCharm or VSCode for example.
- Dive into Git and GitHub. Watch some videos, this takes some time to click. GitHub Desktop is great.
https://github.dev/mesa/mesais great for small changes (to docs).
Learn the tools, talk to us about what you want to change, and open a small PR once direction is clear. For enhancements/new features, get maintainer approval in an issue/discussion first. Or update an example model (check open issues)!
Awesome! You have the basics of open-source software development (if not check above), but not much modelling experience.
First step is to start thinking like a modeller. To understand the fine details about our library and contribute meaningfully, get some modelling experience:
- Go though our series of introductory tutorials at Getting Started. While going through them, dive into the source code to really see what everything does.
- Follow an ABM course (if possible). They might be a bit outdated programming language wise, but conceptual they're sound.
- This MOOC on ABM concepts: Agent Based Modeling
- This MOOC on practical ABM modelling: Agent-Based Models with Python: An Introduction to Mesa
- Go though multiple of our examples. Play with them, modify things and get a feel for Mesa and ABMs.
- Check our open issues for the examples.
- If you see anything you want to improve, feel free to open a (small) PR for bug fixes/docs. For enhancements/new features, discuss first and wait for maintainer approval.
- If you have a feel for Mesa, check our discussions and issues.
- Also go through our release notes to see what we recently have been working on, and see some examples of successful PRs.
- Once you found or thought of a nice idea, comment on the issue/discussion (or open a new one) and get to work!
That's great! You can start with bug fixes, docs, or tests right away. For enhancements/new features, align in an issue/discussion and wait for maintainer approval before opening a PR. Reach out to us anytime, start small but don't be afraid to dream big!
Start with creating your own models, for fun. Once you have some experience, move to the topics above.
Mesa is a library that aims to provide elegant, scalable, flexible, and powerful building blocks to a wide audience of agent-based modellers. When contributing, it helps to understand our development philosophy and process.
- Bug fixes: For clear, scoped bugs, opening a PR directly is usually fine. For larger or uncertain bug fixes, open an issue or discussion first.
- Enhancements and new features: Open an issue or discussion first, agree on direction with maintainers, and wait for explicit approval before opening a PR.
- No prior approval for feature/enhancement work: PRs may be closed until there is maintainer alignment and approval to proceed.
- When in doubt: Start with a Discussion. It's always easier to move from discussion to implementation than to rework a large PR.
For significant features, we typically follow a three-stage process. While not always linear, this flow helps ensure we build the right thing the right way.
Before jumping into solutions, we first align on the problem:
- Target audience: Who is this feature for? What's their experience level and context?
- Use cases: When and why would someone use this? What are they trying to accomplish?
- Existing solutions: What do other libraries offer? What can we learn from or connect to?
- Gap analysis: Given existing solutions (both in Mesa and elsewhere), where are the gaps?
This stage answers the fundamental question: Is this problem worth solving, and are we the right ones to solve it?
Once we agree on the problem, we design the solution at a high level:
- User API: What will the interface look like from a user's perspective? How will modellers interact with this feature?
- Core architecture: What data structures and patterns will we use internally?
- Integration: How does this fit with existing Mesa components?
The goal is to wrap our heads around the conceptual approach before diving into code.
Sometimes the answer is that we just need better documentation. Python itself is a powerful tool and there are many existing libraries in the ecosystem to leverage.
With alignment on both problem and design, implementation can proceed. For enhancements or new features, this stage starts only after maintainers confirm they are open to a PR:
- Write the code following Mesa's standards
- Include/update tests and and check test coverage
- Include/update documentation and check Readthedocs rendering
- Open a PR for review
And if needed:
- Update relevant examples
- Update/extend the tutorial
- Write a section for the migration guide
For complex features where feasibility or proportionality is uncertain, we sometimes use pathfinding PRs. These are exploratory implementations meant to:
- Test whether an approach is technically viable
- Understand the true complexity and scope
- Gather concrete data (e.g., micro-benchmarks) to inform design decisions
- Spark discussion with working code rather than abstract ideas
Pathfinding PRs aren't expected to be merge-ready. They're tools for learning and discussion. If you're exploring a complex feature, consider posting initial results and ideas in a Discussion before opening a full PR.
Here's how this process might look in practice:
- Discussion opened: "I'd think feature X should be in Mesa"
- Problem alignment: Community discusses target users, use cases, existing solutions, and identifies gaps
- Conceptual design: Proposals for user API and architecture are shared and refined
- Pathfinding (if needed): A quick prototype tests feasibility and gathers data
- Implementation PR: Full implementation with tests, docs, and examples
- Review and iteration: Community feedback leads to refinements
- Merge: Feature becomes part of Mesa
Figuring out the right direction is often as valuable as implementing a predefined solution. Don't hesitate to ask questions and propose ideas early in the process!
:target: https://codecov.io/gh/mesa/mesa
:target: https://github.com/astral-sh/ruff
As part of our contribution process, we practice continuous integration and use GH Actions to help enforce best practices.
If you're changing previous Mesa features, please make sure of the following:
- Your changes pass the current tests.
- Your changes pass our style standards.
- Your changes don't break the models or your changes include updated models.
- Additional features or rewrites of current features are accompanied by tests.
- New features are demonstrated in a model, so folks can understand more easily.
Across Mesa, prefer clear and predictable exception behavior:
- Avoid raising generic
Exception; use a specific built-in or Mesa-specific exception instead. - For standard validation and input errors, prefer the most appropriate Python built-in exception.
- Use Mesa-specific exceptions when they add meaningful domain context or hide internal implementation details from callers.
- Follow the existing Mesa exception hierarchy: use the most specific
MesaExceptionsubclass that fits the failure before introducing a new one. - Always check with the maintainers as part of a PR or issue when you think you need a new exception.
- When wrapping internal exceptions, use
raise ... from ...to preserve the original cause. - Write exception messages that are actionable — users should immediately understand what went wrong and how to fix it.
When changing exception behavior, update or add tests to assert the expected exception type and message. To ensure that your submission will not break the build, you will need to install Ruff and pytest.
pip install ruff pytest pytest-covWe test by implementing simple models and through traditional unit tests in the tests/ folder. The following only covers unit tests coverage. Ensure that your test coverage has not gone down. If it has and you need help, we will offer advice on how to structure tests for the contribution.
py.test --cov=mesa tests/With respect to code standards, we follow PEP8 and the Google Style Guide. We use [ruff format] (a more performant alternative to black) as an automated code formatter. You can automatically format your code using pre-commit, which will prevent git commit of unstyled code and will automatically apply ruff style so you can immediately re-run git commit. To set up pre-commit run the following commands:
pip install pre-commit
pre-commit installYou should no longer have to worry about code formatting. If still in doubt you may run the following command. If the command generates errors, fix all errors that are returned.
ruff check . --fixThe license of this project is located in LICENSE. By submitting a contribution to this project, you are agreeing that your contribution will be released under the terms of this license.
Mesa has several roles to help structure our collaboration and recognize great work. They also form a progression path for community members to that want to take on increasing responsibility in the project. Since we're all volunteers, everyone contributes what they can when they can - there are no minimum time commitments. Also, the best ideas and contributions can come from anyone, these roles are just a way to coordinate our efforts.
Feel free to reach out to us anytime to discuss your interests and ambitions in the project. We're always happy to chat about how you can grow your involvement in Mesa!
Contributors help improve Mesa through:
- Code contributions
- Documentation improvements
- Bug reports and fixes
- Example models
- Tutorial improvements
- Answering questions
- Participating in discussions
- Testing pre-releases
- Sharing Mesa with others
Everyone can contribute what they can, when they can. No contribution is too small! Contributors who have a PR successfully merged receive the "Contributor" label on GitHub.
When contributors consistently demonstrate technical skills and community mindset through their contributions, they may be invited to become collaborators. Collaborators help coordinate by:
- Reviewing pull requests
- Triaging issues and discussions
- Coordinating between contributors
- Leading specific areas of development
- Helping new contributors
- Participating in project planning
- Building community
The collaborator role recognizes people who help Mesa grow through both their technical contributions and community involvement. Collaborators receive GitHub triage permissions and the "Collaborator" label.
Maintainers help guide Mesa's overall development while ensuring the project remains sustainable and welcoming. They focus on:
- Project vision and roadmap
- Major architectural decisions
- Release management
- Community governance
- Mentoring collaborators
- Setting community standards
- Long-term sustainability
Maintainers are selected based on their technical expertise, project understanding, and community leadership. Maintainers receive full repository permissions and the "Member" label.
In some cases, special roles may be created for specific purposes, such as leading particular initiatives or components within Mesa. These roles are created as needed based on project requirements and may come with specific permissions and labels.
All roles are expected to:
- Follow Mesa's code of conduct
- Communicate respectfully
- Work collaboratively
- Help maintain a welcoming community
- Make decisions transparently
Mesa grows through good ideas and contributions. We're all volunteers working together to make Mesa better. Don't hesitate to reach out to any maintainer to discuss your interests and potential growth within the project!
Mesa maintains a curated set of core examples within the main repository, complemented by a separate mesa-examples repository for community contributions. This two-tier structure balances maintainability with community creativity.
Core examples in the main Mesa repository are classic, well-known agent-based models that demonstrate Mesa's capabilities and serve as learning resources. They are organized into two categories:
- Basic Examples use only stable Mesa features and are ideal starting points for beginners.
- Advanced Examples are more complex models that may use experimental features to demonstrate advanced concepts.
Core examples are:
- Tested in CI, including batch runs and visualizations
- Maintained to high code quality standards
- Updated to work with each Mesa release
- Documented and included in ReadTheDocs
- Some are used in performance benchmarking
The mesa-examples repository serves as a gallery for user-contributed models and creative applications of Mesa. We welcome diverse contributions here with more relaxed maintenance requirements. Examples in this repository should include:
- A clear README explaining the model
- Requirements or environment files for reproducibility
- Working code compatible with at least one Mesa major version
We accept contributions liberally to this repository to showcase the breadth of Mesa applications, even if we cannot actively maintain all examples long-term.
When contributing a new example, consider:
- For core examples: Propose additions through a GitHub discussion first. Core examples should be:
- widely-recognized canonical models
- demonstrate specific Mesa features effectively (that are not already sufficiently demonstrated by other models)
- For community examples: Open a PR directly to mesa-examples with your model, README, and environment file.
- Improving existing examples: PRs to update or enhance any example are always welcome in either repository.
This structure allows us to maintain a stable, high-quality set of learning resources while encouraging community creativity and diverse applications of Mesa.
Historical context and further motivation can be found in discussion #2330 and PR #2349.
Some notes useful for Mesa maintainers.
To create a new release, follow these steps:
- Ensure all pull requests (PRs) have a clear title and are labeled with at least one label. Check this link to see if all PRs are labeled. These labels will be used when drafting the changelog using the
.github/release.ymlconfiguration. - Navigate to the Releases section in the GitHub UI and click the Draft a new release button.
- Specify the upcoming tag in the Choose a tag and Release title fields (e.g.,
v3.0.0).- For pre-releases, add a
a,borrcand a number behind the version tag (see Versioning), and check the box Set as a pre-release.
- For pre-releases, add a
- Use the Generate release notes button to automatically create release notes. Review them carefully for accuracy, and update labels and edit PR titles if necessary (step 1).
- Write a Highlights section summarizing the most important features or changes in this release.
- Copy the release notes and save them by clicking the grey Save draft button.
- Open a new PR to update the version number in
mesa/__init__.pyand add the copied release notes to theHISTORY.md. - Once this PR is merged, return to the Releases section and publish the draft release.
- The
release.ymlCI workflow should automatically create and upload the package to PyPI. Verify this on PyPI.org. - Finally, after release, open a new PR to update the version number in
mesa/__init__.pyfor the next release (e.g.,"3.1.0.dev").
A recorded video of this process is available here.
Mesa follows Semantic Versioning (SemVer) and has a structured deprecation process to ensure users have time to migrate to new APIs while maintaining backward compatibility.
When implementing a replacement feature:
- Add the new, stable alternative
- Optionally add a
PendingDeprecationWarningto the old feature (signals intent in source code, hidden by default)
warnings.warn(
"old_feature() will be deprecated in a future release. "
"Use new_feature() instead.",
PendingDeprecationWarning,
stacklevel=2,
)Before active deprecation, all of the following must be complete:
- Documentation updated: All relevant docs and tutorials reflect the new approach
- Migration guide entry added: Clear entry in the Migration Guide explaining what changed and how to update code
- Examples updated: All example models use the new API
The alternative must be available for at least one minor release before adding a FutureWarning. This warning is visible to all users by default.
warnings.warn(
"old_feature() is deprecated and will be removed in Mesa X.0. "
"Use new_feature() instead. "
"See: https://mesa.readthedocs.io/latest/migration_guide.html#section",
FutureWarning,
stacklevel=2,
)Remove the old feature in the next major version.
| Action | Allowed in |
|---|---|
Add alternative + PendingDeprecationWarning |
Any release |
Add FutureWarning |
Minor release (patch only with compelling reason) |
| Remove deprecated feature | Major release only |
For features in mesa.experimental, steps 1–3 can be done simultaneously, and step 4 can occur in any subsequent release (including minor/patch). Experimental features:
- Can be changed or removed in any release
- Don't require a deprecation warning period
- Should still communicate changes through release notes
Following the full process is encouraged when feasible.
Place new entries at the top (newest first). Include:
- Clear heading describing the change
- Brief explanation of what changed and why
- Before/after code examples
- Links to relevant PRs/issues
## Mesa X.Y.0
### Feature Name Change
Brief description of what changed and why.
```python
# Old
old_method()
# New
new_method()
```
- Ref: [PR #1234](https://github.com/mesa/mesa/pull/1234), [Documentation](link)A special thanks to the following projects who offered inspiration for this contributing file.