Contributing to WordPress core

Find a ticket, set up the core development environment, write a tested patch and take it through review.

  • Intermediate
  • 9 min read
  • Updated 17 Oct 2026

What you will learn

  • Set up the core development environment
  • Submit a patch
  • Find a suitable first ticket on Trac
  • Run the core PHPUnit tests and coding standards checks

Before you start

  • Debugging WordPress
  • Comfortable with Git branches, commits and pull requests
  • Docker, Node.js and npm installed

Everything you have used in this course, from hooks to the REST API, was written by contributors. WordPress is open source, and its development happens in public: anyone can report a bug, propose a fix and see it ship to every WordPress site. Contributing is also one of the fastest ways to understand core deeply, because you read it with a specific question in mind.

This lesson walks the full path for a code contribution to core. The block editor lives in a separate project with its own workflow; the Gutenberg course covers that side.

Ways to contribute

Code is one route among many. The Make WordPress teams cover documentation, testing, translation, accessibility, performance, support and more, each with a site under make.wordpress.org.

Good first contributions that do not need a patch:

  • Testing patches. Applying someone else's fix, checking it works and reporting the result moves tickets forward and is always needed.
  • Reproducing bugs. Confirming a report, with steps and environment details, helps committers decide what to do.
  • Triage. Finding duplicates and asking reporters for missing details.
  • Documentation. Improving inline docs and handbooks.

All of these build the context that makes your later patches better.

Where the work happens

PlaceWhat it is
Core TracThe issue tracker for core. Every bug, enhancement and task is a numbered ticket.
wordpress-developThe development repository, with source, build tools and tests. Officially in Subversion, mirrored to Git and GitHub.
GitHub pull requestsThe usual way to submit a patch, linked to a Trac ticket.
Make WordPress SlackReal-time discussion. The #core channel and its weekly developer chat are where releases are coordinated.
make.wordpress.org/coreAnnouncements, proposals, meeting notes and developer notes for each release.

You need a WordPress.org account to comment on Trac and to join Slack. Connect your GitHub account to your WordPress.org profile so contributions through pull requests are credited to you.

Finding a ticket

Trac tickets carry keywords that describe their state. The ones to know:

KeywordMeaning
good-first-bugsSelected as suitable for new contributors
needs-patchAgreed problem, no fix yet
has-patchA patch or pull request exists
needs-testingSomeone needs to test the patch
needs-unit-testsThe patch needs automated tests
needs-refreshThe patch no longer applies cleanly to trunk
reporter-feedbackWaiting for more information from the reporter

Trac has saved reports, including one for good first bugs. Choose a ticket in an area you already know, such as options, the REST API or a template function you have used.

Before starting, read the whole ticket. Check whether someone is already working on it and whether the approach has been agreed. If it is unclear, comment with your proposed approach and ask. A short comment saves you writing a patch nobody wants.

Setting up the development environment

The core repository includes a Docker-based local environment, so you do not need a separate stack. You need Git, Node.js with npm, and Docker running. Composer is useful for the coding standards tools.

Shell
git clone https://github.com/WordPress/wordpress-develop.git
cd wordpress-develop

npm install
npm run build:dev

npm run env:start
npm run env:install
  • npm run build:dev builds the JavaScript and CSS that core needs.
  • npm run env:start starts the containers; npm run env:install installs a fresh WordPress into them.
  • The site runs on a local port printed in the output, with the admin login details shown during installation.

Other commands you will use:

Shell
# Run a WP-CLI command inside the environment.
npm run env:cli -- option get siteurl

# Stop the environment when you are done.
npm run env:stop

Fork the repository on GitHub and add your fork as a remote so you can push branches to it:

Shell
git remote add fork git@github.com:your-username/wordpress-develop.git

The environment's configuration can be adjusted with a .env file copied from the provided example. Read the repository's README for current options, as details change between releases.

Running the tests

Core has a large PHPUnit test suite. With the environment running:

Shell
# The whole PHP suite (this takes a while).
npm run test:php

# Only tests in one group.
npm run test:php -- --group option

# Only tests whose names match a pattern.
npm run test:php -- --filter Tests_Option

Tests live under tests/phpunit/tests/, organised by area. Find the tests for the code you are changing first: they show how the function is meant to behave and give you a pattern to copy.

Coding standards

Core follows the WordPress Coding Standards, checked with PHP_CodeSniffer and the configuration in the repository:

Shell
composer install
vendor/bin/phpcs src/wp-includes/option.php

Run it on the files you changed. Patches that introduce standards errors will be sent back.

Writing the patch

Work on a branch named after the ticket:

Shell
git checkout trunk
git pull origin trunk
git checkout -b 12345-fix-option-sanitisation

Then follow a test-first rhythm:

  1. Reproduce the bug in the local environment, exactly as the ticket describes.
  2. Write a failing test that captures it. A test that fails before your fix and passes after is the strongest argument for a patch.
  3. Make the smallest change that fixes it. Resist refactoring nearby code in the same patch; reviewers need to see exactly what changed and why.
  4. Keep backward compatibility. Core runs on a huge number of sites with plugins that depend on current behaviour. Do not change function signatures, remove hooks or change return types without discussion on the ticket.
  5. Document new code. New functions, hooks and parameters need DocBlocks. Leave the @since version for the committer to confirm if you are unsure which release it will land in.
  6. Run the related tests and the standards check.

Commit with a clear message describing the change. The committer writes the final commit message in core, including props for everyone who helped.

Submitting it

The usual route is a pull request to the WordPress/wordpress-develop repository on GitHub, targeting trunk:

Shell
git push fork 12345-fix-option-sanitisation

Open the pull request and put the full Trac ticket URL in its description, for example Trac ticket: https://core.trac.wordpress.org/ticket/12345. That link connects the pull request to the ticket, where the discussion and decisions happen. Pull requests on this repository are for review only; changes are committed to core through Subversion by committers.

Then comment on the Trac ticket: summarise the approach, explain how to test it, and make sure the has-patch keyword is present. Uploading a .diff file to the ticket is still accepted as an alternative to a pull request.

Review and getting it committed

Patches are reviewed by other contributors and component maintainers, and committed by core committers. Expect questions and requests for changes. Respond on the ticket, update your branch, and add needs-refresh or remove it as appropriate.

Some things that help a patch move:

  • Clear testing instructions. Steps a tester can follow in a few minutes.
  • Tests included. Patches without tests often stall on needs-unit-tests.
  • Patience with the release cycle. Tickets are assigned to milestones. During beta and release candidate phases, only fixes for regressions in that release are usually committed, and enhancements wait for the next cycle.
  • Raising it at the right place. If a ticket with a ready patch is waiting, mention it in the relevant component's channel or the developer chat's open floor, politely. Do not message committers privately to push your ticket.

When the change is committed, the commit message lists props, and your WordPress.org profile records the contribution.

Testing other people's patches

Testing is the most needed contribution and the best way to learn the process. For a pull request:

  1. Check out the branch, or apply the patch, in your local environment.
  2. Reproduce the bug on trunk first so you know what "broken" looks like.
  3. Apply the patch and follow the testing instructions.
  4. Post a test report on the Trac ticket: the patch tested, your environment (WordPress, PHP, database and browser versions where relevant), the steps, the expected result and the actual result.

A concise, reproducible test report is valuable whether the patch passes or fails.

Security issues are different

Never report a security vulnerability on Trac, GitHub or Slack. Public reports put every site at risk before a fix exists. Report it privately through the process on WordPress.org's security page, and follow the security team's guidance on disclosure.

Summary

  • Core development happens in public: tickets on Trac, code in wordpress-develop, discussion in Make WordPress Slack and blogs.
  • Start with testing and triage, then pick a good-first-bugs or needs-patch ticket in an area you know, and agree the approach on the ticket.
  • Set up with npm install, npm run build:dev, npm run env:start and npm run env:install; run tests with npm run test:php.
  • Write a failing test, make the smallest backward-compatible fix, and check coding standards with PHPCS.
  • Submit a pull request linked to the Trac ticket, add testing instructions, and respond to review patiently through the release cycle.
  • Report security issues privately, never in public trackers.

Further reading