Welcome to the esp-hal Contributing Guide
June 10, 2026 · View on GitHub
Thank you for considering contributing to our project! Your efforts help make esp-hal a better ecosystem for everyone.
This guide outlines the contribution workflow, from reporting issues and submitting pull requests, to the review process and eventual merger of contributions.
Quick Navigation
New Contributor Guide
Welcome aboard! If you're new to esp-hal or open-source contribution, here are some resources to get you started:
- Intro to Open Source Contribution: GitHub's Guide
- Setting Up Git
- Workflow Insights: GitHub Flow
- Collaborating via Pull Requests
Before adding or changing code, review the esp-rs developer guidelines.
Getting Started
Issues: Reporting and Resolving
Reporting a New Issue
Encountered a problem or have an idea? First, check existing issues to avoid duplicates. If your concern is new, use our issue form to submit it.
Working on an Issue
Browse existing issues to find one that resonates with you. Use labels for easier filtering. If you decide to tackle an issue, it's courteous (but not mandatory) to let others know by commenting.
Making Changes: Fork, Edit, and Pull Request
- Fork: Start by forking the repository. This keeps the main project safe while you make your changes.
- Setup: Ensure you have the latest Rust toolchain via rustup.rs.
- Branch: Create a branch in your fork for your changes. Keep your changes focused and limited to a single issue or feature.
What You Should Do:
- API changes: If your contribution changes the API, please adapt the driver (including module level documentation) and examples accordingly and update the HIL (Hardware-in-the-Loop) tests.
- Run Related Examples: After making changes, run any affected examples to ensure they build successfully and perform as expected.
- Manual Testing: For hardware-related changes, manually test your changes on the actual devices when possible. If not, please note it in the corresponding issue, and someone from our team will assist with testing. This is crucial because hardware behavior can sometimes differ from what's simulated or expected.
- HIL Tests: Ensure that any changes to the API or hardware interaction logic are reflected in the HIL tests located in the
hil-testdirectory. This helps verify the real-world applicability of your changes.
By taking these extra steps to test your contributions, you help maintain the high quality and reliability of esp-hal, ensuring it remains a robust platform for everyone.
Testing Your Contributions
Ensuring the quality and reliability of esp-hal is a shared responsibility, and testing plays a critical role in this process. Our GitHub CI automatically checks the buildability of all examples and drivers within the project. However, automated tests can't catch everything, especially when it comes to the nuanced behavior of hardware interactions. So make sure that the example affected by your change works as expected.
Further steps that can (or should) be taken in testing:
- Using xtask, build examples for the specified chip.
- When documentation or doctests change, run
cargo xtask build documentationandcargo xtask run doc-tests <CHIP>to build the documentation and run the doctests. To reduce build/test time, use--packagesto specify the package(s) and--chips(for documentation builds) to specify the target chip(s). - Run the HIL tests locally if changes have been made to them.
- Run host-side unit tests with
cargo xtask host-tests(orcargo xtask host-tests <package>). When adding#[test]functions to a package for the first time, also add a match arm for that package inrun_host_testsinxtask/src/lib.rs— see [xtask/README.md#host-tests].
For detailed instructions on how to use our HIL tests with comment commands, see the HIL guide.
Commit Your Updates
Commit your changes once you're satisfied. Review your own work to streamline the review process later. Use rustfmt and cargo clippy to ensure your code adheres to Rust's conventions.
rustup component add rustfmt
rustup component add clippy
We strongly recommend that you format your code before committing to ensure consistency throughout the project. To format all packages in the workspace, run the following command in a terminal from the root of the repository:
cargo xtask fmt-packages
We also recommend using the lint-packages subcommand, which uses cargo clippy and will lint the entire driver in order to catch common mistakes in the code.
cargo xtask lint-packages
This will use rustfmt to ensure that all source code is formatted correctly prior to committing.
Pull Request: From Submission to Merge
- Fill the pull request template so that we can review your PR. This template helps reviewers understand your changes as well as the purpose of your pull request.
- Link your PR to any relevant issues it addresses.
- Allow edits from maintainers so the branch can be updated for a merge. Once you submit your PR, a Docs team member will review your proposal. We may ask questions or request additional information.
- If your change is user-visible, consider adding a brief changelog entry and/or migration guide note in the PR description using the structured sections provided by the template (see below). This is optional — if you skip it, a maintainer will either add the entries or apply the
skip-changeloglabel on your behalf. Do not editCHANGELOG.mdfiles directly — those are updated automatically at release time. - If your change requires user code to be updated, add a
# Migration guidesection. Each breaking change needs a## crate/areaheading and a### Titlefor the specific change, followed by the migration steps. - We may ask for changes to be made before a PR can be merged, either using suggested changes or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch.
- As you update your PR and apply changes, mark each conversation as resolved.
- Resolve merge conflicts if they arise, using resources like this git tutorial for help.
Changelog and Migration Guide Entries
Changelog entries are optional for contributors. If you don't add them a
maintainer will either write them or apply the skip-changelog label before the
PR is merged.
If you do want to document your change, add entries directly in the PR description
using the structured sections in the template. Do not edit CHANGELOG.md —
those files are updated automatically at release time from the PR descriptions.
Format
Use # Changelog and # Migration guide as top-level headings (H1). Under each
heading, group entries using H2 headings. Changelog H2 headings may use just the
crate name (e.g. ## esp-hal), while migration guide H2 headings must include
an area (e.g. ## esp-hal/SPI driver).
# Changelog
## esp-hal
- Added: Support for the Foo peripheral.
- Fixed: A bug in the Bar driver that caused incorrect output.
## esp-hal/SPI driver
- Changed: `SpiDevice::transfer` now accepts a mutable slice.
# Migration guide
## esp-hal/SPI driver
### `SpiDevice::transfer` signature changed
`SpiDevice::transfer` now takes `&mut [u8]` instead of `(&[u8], &mut [u8])`.
Update your call sites accordingly.
Entry kinds
Each item in the # Changelog section must begin with one of:
| Kind | When to use |
|---|---|
Added | New public API, feature, or peripheral support |
Changed | Behaviour or API change (non-breaking preferred) |
Fixed | Bug fixes |
Removed | Removed API or feature |
Skipping the changelog for a specific crate
If your PR touches a published crate but the change genuinely needs no
user-visible entry (e.g. a documentation fix, an internal refactor, or a
build-system tweak), you can exempt that crate by writing the special marker
as the sole item in its # Changelog section:
# Changelog
## esp-metadata
- No changelog necessary.
This tells CI that the omission is intentional. The marker must be the only item in the section — combining it with real entries is an error.
When the whole PR needs no changelog at all, a maintainer can apply the
skip-changelog label instead.
Manually editing CHANGELOG.md
In rare cases — such as backports, hotfixes, or curated release notes that
cannot be expressed through the structured PR description format — a maintainer
can apply the manual-changelog label to a PR. This label:
- Allows direct edits to
CHANGELOG.mdfiles (the automated "no direct CHANGELOG.md edits" check is skipped). - Skips the per-package coverage check (the PR is not required to have structured entries in the description).
- Still validates any PR description entries that are present, as a safety net against formatting accidents.
Do not use manual-changelog for routine changes — the structured PR
description format exists precisely to keep changelog maintenance consistent
and automatable.
Validation
You can validate your PR description locally before pushing:
# Pipe the body directly:
echo "# Changelog\n\n## esp-hal\n\n- Added: Something." | cargo xtask check-pr-changelog
# Or validate an open PR by number (requires the `gh` CLI):
cargo xtask check-pr-changelog --pr 1234
CI will also validate the format automatically on every PR.
Your PR is Merged!
Congratulations! The esp-rs team thanks you for your contributions!
Contributing to open source extends beyond just code! Each contribution, regardless of size, plays a significant role. We appreciate your involvement in this collective endeavor.