… admonition:: Check your version!

Things can change quickly, and so does this contributor guide.
To make sure you've got the most cutting edge version of this guide,
go check out the
`latest version <https://docs.ray.io/en/master/ray-contribute/getting-involved.html>`__.

Getting involved and contributing#

Ray is more than a framework for distributed applications. It’s also an active community of developers, researchers, and folks who love machine learning.

Tip

Ask questions on our forum! The community is extremely active in helping people succeed in building their Ray applications.

You can join (and Star!) us on GitHub.

Contributing to Ray#

We welcome and encourage all forms of contributions to Ray, including but not limited to:

  • Code reviewing of patches and PRs.

  • Pushing patches.

  • Documentation and examples.

  • Community participation in forums and issues.

  • Code readability and code comments to improve readability.

  • Test cases to make the codebase more robust.

  • Tutorials, blog posts, talks that promote the project.

  • Features and major changes via Ray Enhancement Proposals (REP).

What can I work on?#

We use GitHub labels to categorize issues and help contributors find work that matches their interests and skill level.

Getting started#

If you’re new to Ray, start with these labels:

  • good-first-issue: Small issues that are good for new contributors to onboard to the codebase.

  • contribution-welcome: Impactful issues that are good candidates for community contributions. We prioritize reviews for these issues.

By component#

Find issues in the area you’re most interested in:

  • core: Ray Core (tasks, actors, objects, scheduling).

  • data: Ray Data for distributed data processing.

  • train: Ray Train for distributed training.

  • tune: Ray Tune for hyperparameter tuning.

  • serve: Ray Serve for model serving.

  • rllib: RLlib for reinforcement learning.

By type#

Choose the kind of contribution you’d like to make:

  • bug: Bug fixes.

  • enhancement: New features or improvements.

  • docs: Documentation improvements.

You can combine labels in GitHub’s search to find issues that match multiple criteria.

Setting up your development environment#

To edit the Ray source code, fork the repository, clone it, and build Ray from source. Follow these instructions for building a local copy of Ray to make changes.

AI-assisted contributions#

If you contribute with the help of an AI coding agent, Ray ships an AGENTS.md at the repository root. Tools that support the AGENTS.md convention load it into the agent’s context automatically, and Claude Code loads it through .claude/CLAUDE.md. It defines the contribution policy AI-assisted PRs are expected to follow, including duplicate-work checks, no low-value busywork PRs, and a human accountability requirement.

The file is reproduced below as an FYI, so you can see exactly what your tools are instructed to do:

# Agent Instructions for Ray

> These instructions apply to **all** AI-assisted contributions to `ray-project/ray`.
> PRs that ignore this policy may be closed without review.

Ray is a high-traffic repository. Every PR notifies CODEOWNERS, triggers CI, and
consumes maintainer attention. Automated, low-value, or duplicate contributions
create real cost for the people who maintain the project. Follow the rules below
before opening any PR with AI assistance.

## 1. Contribution Policy (Mandatory)

### Duplicate-work checks

Before proposing a PR, confirm the work is not already in flight:

```bash
# If you are addressing an existing issue:
gh issue view <issue_number> --repo ray-project/ray --comments
gh pr list --repo ray-project/ray --state open --search "<issue_number> in:body"

# Search open PRs for the same area before starting:
gh pr list --repo ray-project/ray --state open --search "<short area keywords>"
```

- If an open PR already addresses the same change, do not open another. Comment
  on the existing PR instead.
- If your approach is materially different, explain the difference in the issue
  or the existing PR thread before opening a competing PR.

### No low-value busywork PRs

Do not open one-off PRs for trivial edits (a single typo, an isolated style
tweak, one mutable default, a lone type annotation, etc.). Mechanical cleanups
are acceptable only when bundled with substantive work, or when coordinated with
maintainers first. Mass-generated "cleanup" PRs are not welcome.

### Accountability

- Pure code-agent PRs are **not allowed**. A human submitter must understand and
  defend the change end-to-end.
- The submitting human must review every changed line and run the relevant tests
  locally before requesting review.
- PR descriptions for AI-assisted work **must** state:
    - Why this is not duplicating an existing issue or PR.
    - The test commands run and their results.
    - That AI assistance was used.

### Fail-closed behavior

If the requested work is a duplicate, trivial busywork, or cannot be tested and
defended by a human, **do not open a PR**. Return a short explanation of what is
missing instead.

## 2. Development Workflow

Ray is a unified framework for scaling AI and Python applications. Its source is
laid out as:

- `src/ray/`: C++ core runtime
- `python/ray/`: Python API and libraries (data, serve, train, tune)
- `rllib/`: RLlib (symlinked from `python/ray/rllib`)
- `doc/source/`: Sphinx documentation

The default test timeout is 180s (`pytest.ini`). For build, test, lint, and
code-style details, follow Ray's existing guides rather than duplicating them
here:

- Setting up a dev environment and code style:
  [`doc/source/ray-contribute/getting-involved.md`](doc/source/ray-contribute/getting-involved.md)
- Building Ray:
  [`doc/source/ray-contribute/development.md`](doc/source/ray-contribute/development.md)
- General contribution process: [`CONTRIBUTING.rst`](CONTRIBUTING.rst)

### Required for every commit

- **DCO sign-off.** All commits require a Developer Certificate of Origin
  sign-off. Always commit with `-s`:

  ```bash
  git commit -s -m "Your commit message"
  ```

- **Pre-commit hooks.** Install pre-commit. With `pre-commit install`, the hooks
  run automatically on staged files at commit time:

  ```bash
  pip install -U pre-commit==3.5.0 && pre-commit install
  pre-commit run
  ```

- **Python environments.** Use a virtual environment for all Python work. Never
  install into system Python.

## 3. Editing these instructions

Changes to this file affect every AI-assisted contribution to Ray. Open a
dedicated PR for any change to `AGENTS.md`, explain the motivation, and tag the
maintainers who own contribution policy for review.

Submitting and merging a contribution#

To merge a contribution, complete the following steps:

  1. First merge the most recent version of master into your development branch.

    git remote add upstream https://github.com/ray-project/ray.git
    git pull . upstream/master
    
  2. Make sure all existing tests and linters pass. Run setup_hooks.sh to create a git hook that runs the linter before you push your changes.

  3. If introducing a new feature or patching a bug, be sure to add new test cases in the relevant file in ray/python/ray/tests/.

  4. Document the code. Document public functions, and remember to provide a usage example if applicable. See doc/README.md for instructions on editing and building public documentation.

  5. Address comments on your PR. During the review process you may need to address merge conflicts with other changes. To resolve merge conflicts, run git pull . upstream/master on your branch. Don’t use rebase, because it’s less friendly to the GitHub review tool. We squash all commits on merge.

  6. Reviewers approve and merge the pull request. Be sure to ping them if the pull request is getting stale.

PR review process#

For contributors in the ray-project organization#

  • When you first create a PR, add a reviewer to the assignee section.

  • Assignees review your PR and add the @author-action-required label if further action is required.

  • Address their comments and remove the @author-action-required label from the PR.

  • Repeat this process until assignees approve your PR.

  • Once the PR is approved, the author is in charge of ensuring the PR passes the build. Add the test-ok label if the build succeeds.

  • Committers merge the PR once the build passes.

For contributors not in the ray-project organization#

  • Your PRs will have assignees shortly. Assignees of PRs actively engage with contributors to merge the PR.

  • Actively ping assignees after you address your comments!

Testing#

Even though we have hooks to run unit tests automatically for each pull request, we recommend running unit tests locally beforehand to reduce reviewers’ burden and speed up the review process.

If you’re running tests for the first time, you can install the required dependencies with:

pip install -c python/requirements_compiled.txt -r python/requirements/test-requirements.txt

Testing for Python development#

The full suite of tests is too large to run on a single machine. However, you can run individual relevant Python test files. Suppose one of the tests in a file such as python/ray/tests/test_basic.py is failing. You can run just that test file locally as follows:

# Directly calling `pytest -v ...` may lose import paths.
python -m pytest -v -s python/ray/tests/test_basic.py

This runs all the tests in the file. To run a specific test, use the following:

# Directly calling `pytest -v ...` may lose import paths.
python -m pytest -v -s test_file.py::name_of_the_test

Testing for C++ development#

To compile and run all C++ tests, you can run:

bazel test $(bazel query 'kind(cc_test, ...)')

Alternatively, you can run one specific C++ test:

bazel test $(bazel query 'kind(cc_test, ...)') --test_filter=ClientConnectionTest --test_output=streamed

Code style#

In general, we follow the Google style guide for C++ code and the Black code style for Python code. Python imports follow PEP8 style. However, it’s more important for code to be in a locally consistent style than to strictly follow guidelines. Whenever in doubt, follow the local code style of the component.

For Python documentation, we follow a subset of the Google pydoc format. The following code snippets demonstrate the canonical Ray pydoc formatting:

def ray_canonical_doc_style(param1: int, param2: str) -> bool:
    """First sentence MUST be inline with the quotes and fit on one line.

    Additional explanatory text can be added in paragraphs such as this one.
    Do not introduce multi-line first sentences.

    Examples:
        .. doctest::

            >>> # Provide code examples for key use cases, as possible.
            >>> ray_canonical_doc_style(41, "hello")
            True

            >>> # A second example.
            >>> ray_canonical_doc_style(72, "goodbye")
            False

    Args:
        param1: The first parameter. Do not include the types in the
            docstring. They should be defined only in the signature.
            Multi-line parameter docs should be indented by four spaces.
        param2: The second parameter.

    Returns:
        The return value. Do not include types here.
    """
class RayClass:
    """The summary line for a class docstring should fit on one line.

    Additional explanatory text can be added in paragraphs such as this one.
    Do not introduce multi-line first sentences.

    The __init__ method is documented here in the class level docstring.

    All the public methods and attributes should have docstrings.

    Examples:
        .. testcode::

            obj = RayClass(12, "world")
            obj.increment_attr1()

    Args:
        param1: The first parameter. Do not include the types in the
            docstring. They should be defined only in the signature.
            Multi-line parameter docs should be indented by four spaces.
        param2: The second parameter.
    """

    def __init__(self, param1: int, param2: str):
        #: Public attribute is documented here.
        self.attr1 = param1
        #: Public attribute is documented here.
        self.attr2 = param2

    @property
    def attr3(self) -> str:
        """Public property of the class.

        Properties created with the @property decorator
        should be documented here.
        """
        return "hello"

    def increment_attr1(self) -> None:
        """Class methods are similar to regular functions.

        See above about how to document functions.
        """

        self.attr1 = self.attr1 + 1

See How to write code snippets for more details about writing code snippets in docstrings.

Lint and formatting#

We also have tests for code formatting and linting that need to pass before merge.

pip install -c python/requirements_compiled.txt -r python/requirements/lint-requirements.txt

You can run the following locally:

pip install -U pre-commit==3.5.0
pre-commit install  # automatic checks before committing
pre-commit run ruff -a

Output such as the following indicates failure:

WARNING: clang-format is not installed!  # This is harmless
From https://github.com/ray-project/ray
 * branch                master     -> FETCH_HEAD
python/ray/util/sgd/tf/tf_runner.py:4:1: F401 'numpy as np' imported but unused  # Below is the failure

In addition, there are other formatting and semantic checkers, such as the following, that aren’t included in pre-commit:

  • Python README format:

cd python
python setup.py check --restructuredtext --strict --metadata
  • Python and docs banned words check

./ci/lint/check-banned-words.sh
  • Bazel format:

./ci/lint/bazel-format.sh
  • clang-tidy for C++ lint, requires clang and clang-tidy version 12 to be installed:

./ci/lint/check-git-clang-tidy-output.sh

Understanding CI test jobs#

The Ray project automatically runs continuous integration (CI) tests once a PR is opened using Buildkite with multiple CI test jobs.

The CI test folder contains all integration test scripts, which invoke other test scripts via pytest, bazel-based tests, or other bash scripts. Examples include:

  • Bazel test command:

    • bazel test --build_tests_only //:all

  • Ray serving test commands:

    • pytest python/ray/serve/tests

    • python python/ray/serve/examples/echo_full.py

If a CI build exception doesn’t appear to be related to your change, check recent tests known to be flaky.

API compatibility style guide#

Ray provides stability guarantees for its public APIs in Ray core and libraries, which are described in the API Stability guide.

It’s hard to fully capture the semantics of API compatibility in a single annotation. For example, public APIs may have “experimental” arguments. Note more granular stability contracts in the pydoc, for example, “the random_shuffle option is experimental”. When possible, prefix experimental arguments with underscores in Python, for example, _owner=.

Other recommendations:

In Python APIs, consider forcing the use of kwargs instead of positional arguments (with the * operator). Kwargs are easier to keep backward compatible than positional arguments. For example, if you needed to deprecate “opt1” below, it’s easier with forced kwargs:

def foo_bar(file, *, opt1=x, opt2=y)
    pass

For callback APIs, consider adding a **kwargs placeholder as a “forward compatibility placeholder” in case you need to pass more args to the callback in the future, for example:

def tune_user_callback(model, score, **future_kwargs):
    pass

Community examples#

We’re always looking for new example contributions! When contributing an example for a Ray library, include a link to your example in the examples.yml file for that library:

 - title: Serve a Java App
   skill_level: advanced
   link: tutorials/java
   contributor: community

Give your example a title, a skill level (beginner, intermediate, or advanced), and a link. Relative links point to other documentation pages, but direct links starting with http:// also work. Include the contributor: community metadata so the example is correctly labeled as a community example in the example gallery.

Becoming a committer#

Committers are experienced contributors who have demonstrated significant contributions to the Ray project over an extended period. Committers have additional responsibilities and privileges within the project.

Eligibility criteria

  • Must be active in the project for at least six months

  • Must be nominated by at least one TSC (Technical Steering Committee) member

  • Must have demonstrated significant contributions to the project, including:

    • High-quality code contributions

    • Thorough code reviews

    • Active participation in community discussions

    • Technical expertise in one or more areas of the project

Responsibilities

Committers are expected to:

  • Review and merge pull requests

  • Ensure code quality and adherence to project standards

  • Help maintain the health and direction of the project

  • Mentor contributors and reviewers

More resources for getting involved#

Ray is more than a framework for distributed applications. It’s also an active community of developers, researchers, and folks who love machine learning. Here’s a list of tips for getting involved with the Ray community:

Note

These tips are based on the TVM contributor guide.