StackPractices
beginner By Mathias Paulenko

CONTRIBUTING.md Template — Contributing Guide

A ready-to-use CONTRIBUTING.md template for open-source and internal projects, with maintainer guidance.

Topics: devops

Overview

A contributing guide — conventionally a CONTRIBUTING.md file at the repository root — is the document that tells people how to report bugs, suggest improvements, submit pull requests, and meet the project’s coding standards. GitHub surfaces it automatically whenever someone opens an issue or a pull request, so it’s the first contract between a project and its contributors.

This resource gives you a complete CONTRIBUTING.md template ready to copy, a filled-in example so you can see how it reads in practice, and maintainer guidance on the parts that usually go wrong: unwritten standards, security reports filed as public bugs, and guides nobody updates.

When to Use

  • Open-source projects — every public repo that accepts external PRs needs one; GitHub links it in the PR form automatically.
  • Internal team repos — the same document doubles as onboarding: new engineers learn the branching model, lint rules, and review etiquette from a single page.
  • After the first external PR — if you found yourself explaining the workflow in a code review comment, that explanation belongs in the guide.

If the project is private and the whole team already knows the conventions, a short section inside the README is usually enough — a separate file adds no value until someone outside the core team starts contributing.

Contribution flow

A contributor’s path from idea to merge looks the same in most repositories:

flowchart diagram: Issue opened

Everything in the template below exists to keep that loop fast: the issue templates feed step one, the coding standards and PR checklist keep reviews short, and the community section tells contributors what happens after merge.

Template

Copy the whole block below into a CONTRIBUTING.md file at your repository root, then replace every [placeholder] with your project’s real values.

# Contributing to [Project Name]

Thanks for your interest in contributing! This document explains how to
report bugs, suggest features, and submit changes.

## Table of Contents

- [Ways to Contribute](#ways-to-contribute)
- [Development Setup](#development-setup)
- [Coding Standards](#coding-standards)
- [Pull Request Process](#pull-request-process)
- [Reporting Bugs](#reporting-bugs)
- [Suggesting Features](#suggesting-features)
- [Security Vulnerabilities](#security-vulnerabilities)
- [Community Guidelines](#community-guidelines)
- [Questions](#questions)

## Ways to Contribute

Code is not the only way to help:

- **Report bugs** — open an issue with the bug report template.
- **Suggest features** — describe the problem before proposing a solution.
- **Improve documentation** — fix typos, outdated examples, or unclear steps.
- **Triage issues** — reproduce reports, add missing details, or suggest labels.
- **Answer questions** — help other users in Discussions or the issue tracker.

### Finding issues to work on

Look for the `good first issue` or `help wanted` labels — maintainers curate
those for new contributors. Comment on an issue before starting so nobody
duplicates your work.

## Development Setup

    # 1. Fork the repository on GitHub, then clone YOUR fork
    git clone https://github.com/[your-user]/[repo].git
    cd [repo]

    # 2. Add the original repo as upstream so you can sync later
    git remote add upstream https://github.com/[org]/[repo].git

    # 3. Install dependencies and verify the setup
    [install command]
    [test command]

    # 4. Create a branch for your change
    git checkout -b feature/your-feature-name

## Coding Standards

- Follow the style conventions of the language and framework in use.
- Run the linter before committing: `[lint command]`
- Format code with: `[format command]`
- Add tests for every new feature; keep coverage above [coverage target]%.

### Commit messages

We use [Conventional Commits](https://www.conventionalcommits.org/):

    feat: add email validation to signup form
    fix: resolve null pointer in payment retry
    docs: update API examples for v2 endpoints

Sign your commits if the project requires a DCO (`git commit -s`). Check
`CLA.md` or `DCO.md` in the repository for the policy — some projects accept
contributions without any formal agreement.

## Pull Request Process

1. Branch from `main` using `feature/`, `fix/`, or `docs/` prefixes.
2. Keep the PR focused — one change per pull request.
3. Push to your fork and open a PR with the provided template.
4. Link the related issue: write `Closes #123` in the description.
5. Wait for CI to pass, then address reviewer feedback.
6. A maintainer merges once approved. Squash commits if asked.

### PR checklist

- [ ] Tests added or updated
- [ ] Documentation updated
- [ ] Linter and formatter pass
- [ ] Commit messages follow the convention
- [ ] The PR description explains what and why

## Reporting Bugs

1. Search existing issues first — duplicates get closed.
2. Open a new issue with the bug report template.
3. Include steps to reproduce, expected vs actual behavior, environment
   details (OS, version), and logs or screenshots when relevant.

## Suggesting Features

1. Open an issue describing the problem you want solved, not just the API
   you want added.
2. Wait for maintainer feedback before writing the implementation — large
   features may need an RFC first.
3. Once agreed, follow the pull request process above.

## Security Vulnerabilities

**Do not open a public issue for security problems.** Instead:

- Report them privately through the `SECURITY.md` policy or
  [security contact / advisory URL].
- Include a proof of concept or reproduction steps when possible.
- Expect an acknowledgement within [response time] days.

## Community Guidelines

This project follows the [Code of Conduct](CODE_OF_CONDUCT.md). Be respectful,
assume good intent, and keep feedback about the code — not the person.

Contributors are credited in the README or `CONTRIBUTORS` file and in release
notes.

## Questions

- Open a Discussion for general questions.
- Join [Discord/Slack URL] for real-time chat.
- Email [contact email] for private inquiries.

Filled Example

This is how the first sections of that template look once filled for a fictional Python client library, acme/requests-toolkit:

# Contributing to requests-toolkit

Thanks for your interest in contributing! This document explains how to
report bugs, suggest features, and submit changes.

## Development Setup

    git clone https://github.com/your-user/requests-toolkit.git
    cd requests-toolkit
    git remote add upstream https://github.com/acme/requests-toolkit.git

    python -m venv .venv && source .venv/bin/activate
    pip install -e ".[dev]"
    pytest                    # all tests must pass before you start

## Coding Standards

- Style: black, line length 88, enforced by pre-commit.
- Type-check: mypy --strict on `src/`.
- Tests: add one test per public function; coverage must stay above 90%.

### Commit messages

We use Conventional Commits: `feat:`, `fix:`, `docs:`, `refactor:`, `test:`.
Sign your commits (`git commit -s`) — this project follows the DCO.

## Security Vulnerabilities

Report privately via GitHub Security Advisories — never as a public issue.
We acknowledge reports within 48 hours.

Template sections explained

SectionWhat it doesWhat to customize
Intro + Table of ContentsOrients the reader in a long documentNothing — keep it short
Ways to ContributeWidens the funnel beyond codersYour real channels (Discussions, forum, chat)
Development SetupReproduces a working environmentInstall/test/lint commands, Node/Python versions
Coding StandardsRemoves style debates from reviewsLint/format commands, coverage target, DCO vs CLA
Pull Request ProcessSets expectations about reviewBranch prefixes, review count, squash policy
Security VulnerabilitiesKeeps exploits out of public issuesAdvisory URL or security email, response SLA
Community GuidelinesPoints to enforcement rulesLink your code of conduct and moderation contact

Two sections people routinely forget: security reporting (a public issue announcing a vulnerability is itself a security incident) and the license note (state that contributions are accepted under the project’s license — it’s a one-line legal protection).

Adapting the guide to your project

A contributing guide should match the maintainer capacity behind it, not the project’s ambition. A guide that promises “maintainers review within 48 hours” from a team of two weekend volunteers erodes trust faster than having no guide at all. Write the rules you can actually keep, then tighten them as the project grows.

Project sizeKeep from the templateAddSkip for now
Solo / hobby projectSetup, coding standards, PR process, security contactA “what I won’t accept” note saves awkward rejectionsCLA/DCO, RFC process, issue triage rules
Small team (2-10)Everything above + code of conductReview SLA, branch naming, release process noteFormal RFCs, multi-maintainer approval rules
Popular OSS projectThe whole templateDCO or CLA, dedicated triage section, contributor ladderNothing — invest in automation instead

Issue labels worth creating

Labels are the cheapest part of contribution infrastructure. These cover what most projects need on day one:

LabelPurpose
good first issueCurated entry points — the single most effective label for attracting new contributors
help wantedTasks a maintainer would review but can’t prioritize now
bug / enhancementSeparates defects from feature ideas at triage time
documentationGroups the fixes that non-coders can make — pairs with “Ways to Contribute”
needs-triageFlags reports missing reproduction steps or environment details
breaking changeMarks PRs that need a major release and migration notes

Two habits make labels work: keep good first issue populated (a contributor who finds it empty assumes the project is dead) and remove it from anything that stops being beginner-friendly — nothing kills goodwill like a “first issue” that requires two weeks of context.

Real-world examples to learn from

Before publishing your guide, read how large projects handle the same document. Each solves a different problem well:

  • Kubernetes contributor guide — the reference for scale: a short entry document that fans out into detailed per-topic docs. Worth copying when your guide outgrows a single file.
  • Rails CONTRIBUTING.md — the opposite approach: one tight page with strong opinions (what they will and won’t merge). Good model for small teams that want to reject work early.
  • VS Code CONTRIBUTING.md — best-in-class “Ways to Contribute” section that lists non-code paths first and keeps the bar friendly without lowering standards.

Notice what none of them do: none bury the security reporting path, none leave the setup commands ambiguous, and none promise review times they can’t meet. Those three details are where most contributing guides fail quietly.

Common Mistakes

  • Writing the guide once and never updating it. A contributing guide that still references the old test command teaches contributors to ignore it. Review it with every release, like you review the changelog.
  • Standards that live only in reviewers’ heads. If the linter doesn’t enforce a rule, contributors can’t know it — either document it or don’t enforce it in review.
  • A CLA that scares contributors away. Long legal documents read at PR time deter first-timers; a DCO (git commit -s) covers most projects. If legal requires a CLA, say so plainly at the top of the guide.
  • Treating every contribution the same. A typo fix doesn’t need an RFC, but a 40-file refactor does. State the threshold for “talk to us first” so contributors don’t burn days on a rejected PR.
  • No security channel. Without a private reporting path, a vulnerability lands in a public issue where anyone can read it.

Troubleshooting

  • PRs sit unanswered for weeks: it’s almost always a maintainer-capacity problem, not a contributor problem. Respond to new issues and PRs within a week, even if the answer is “we can’t look at this yet” — silence kills contribution faster than rejection.
  • Contributors keep failing CI: the setup section is wrong or incomplete. Reproduce it yourself from a clean clone; if the guide says “run tests” but tests need a seed database, the guide is the bug.
  • You only get code, never triage or docs: non-code ways to contribute are buried or missing. Move “Ways to Contribute” near the top and label documentation issues explicitly.
  • Repeated style debates in review: the standard isn’t written down (or isn’t automated). Put the rule in the guide and let the linter say no — reviewers shouldn’t be style police.
  • A contributor opens an RFC-sized PR cold: the “talk first” threshold is unclear. State it explicitly — for example, “any change touching more than 3 files or adding a dependency needs an issue first.”

Variants

ContextApproachNotes
Open sourcePublic guide with DCO/CLAInclude code of conduct and security policy
Internal projectGuide with CI/CD workflowFocus on internal standards and deploy gates
MonorepoGuide with scope rulesDocument what belongs in each package
Library / SDKGuide with semver policyAdd a breaking-change communication section

Further Reading

See Also

Frequently Asked Questions

What should a CONTRIBUTING.md include?

At minimum: how to report bugs, how to propose enhancements, how to set up the development environment, coding standards and commit conventions, the pull request process, a private security reporting channel, and a link to the code of conduct. Everything else is optional.

What's the difference between a CLA and a DCO?

A Contributor License Agreement (CLA) is a legal document contributors sign (sometimes for every PR) granting the project rights over their code. A Developer Certificate of Origin (DCO) is lighter: each contributor certifies authorship by adding a Signed-off-by line via git commit -s. Most small and medium projects choose the DCO; CLAs are common in corporate-backed and foundation projects.

How do I write a contributing guide for a small project?

Start from the template above and delete what doesn't apply. A two-maintainer project needs maybe five sections: setup, standards, PR process, security contact, and conduct. Add CLAs, RFC processes, or issue triage flows only when the project actually requires them — a short guide that gets read beats a long one that doesn't.

How do we handle community contributions well?

Respond to issues and PRs within a week — silence discourages contributors more than rejection. Label good first issue candidates so newcomers can start safely. Give constructive review: "consider X because Y" instead of "this is wrong". Recognize contributors in the README and release notes.

What if my contribution gets rejected?

Don't take it personally — a rejected PR usually means the change doesn't fit the roadmap, not that the work is bad. Ask the maintainer what would make it acceptable, or whether the feature belongs in a separate issue first. Iterating on feedback is how most long-term contributors earn commit rights.

How do we keep contribution quality high without scaring people away?

Automate the rules: linter, tests, and build run in CI so the machine enforces style while reviewers discuss design. Write the standard down once — reviewers shouldn't repeat it. Be more patient with first-time contributors; a clear guide plus a forgiving review beats a strict one that empties the funnel.

How do I enforce guidelines without becoming a gatekeeper?

Point to the document, not to yourself — "the guide asks for a reproduction case" reads very differently from "I need a reproduction case". If a rule can't be enforced by CI or a checklist, it probably belongs in reviewer judgment rather than in the guide. And when you bend a rule for a first-time contributor, say so explicitly; visible generosity teaches the community better than silent strictness.