# Contributing to Onyx: Guidelines, Standards, and the Complete Workflow

> Contribute to Onyx by following clear guidelines for GitHub issues, engineering standards, and the fork-and-pull request workflow. Learn the complete contribution process.

- Repository: [Onyx/onyx](https://github.com/onyx-dot-app/onyx)
- Tags: getting-started
- Published: 2026-03-28

---

**Contributing to Onyx requires opening an approved GitHub issue, following strict engineering standards including mandatory Python typing and 500-line PR limits, and submitting via the fork-and-pull request workflow defined in the official contributing guides.**

The **onyx-dot-app/onyx** repository maintains a structured contribution process designed to keep the codebase stable and maintainable. Whether you are fixing a bug or adding a new connector, you must adhere to the three-phase workflow documented in the `contributing_guides/` directory and the root [`CONTRIBUTING.md`](https://github.com/onyx-dot-app/onyx/blob/main/CONTRIBUTING.md) file.

## Getting Your Feature Approved

Before writing code, you must obtain design sign-off through the official contribution process outlined in [`contributing_guides/contribution_process.md`](https://github.com/onyx-dot-app/onyx/blob/main/contributing_guides/contribution_process.md) (lines 3‑24).

1. **Create a GitHub issue** describing the problem, proposed solution, and any architectural considerations.
2. **Gather community interest** through up-votes. If the issue stalls for more than one week, you may email `yuhong@onyx.app` for reviewer attention.
3. **Complete design review** if requested by the core team. For Enterprise-edition contributions, you must sign the *IP Assignment Agreement* located in the `contributing_guides` folder.

## Engineering Standards and Coding Guidelines

Once approved, follow the strict standards defined in [`contributing_guides/best_practices.md`](https://github.com/onyx-dot-app/onyx/blob/main/contributing_guides/best_practices.md) and [`contributing_guides/dev_setup.md`](https://github.com/onyx-dot-app/onyx/blob/main/contributing_guides/dev_setup.md).

### Development Environment Setup

Clone the repository and initialize your local environment according to the setup guide:

```bash
git clone https://github.com/onyx-dot-app/onyx.git
cd onyx

# Activate the Python virtual environment

source .venv/bin/activate

# Install Node dependencies for widget development (if applicable)

cd widget && npm ci

```

### Strict Typing Requirements

All Python code must be strictly typed. As stated in the best-practices guide (lines 31‑34), "Everything should be **as strictly typed as possible**."

```python
from pydantic import BaseModel

class EmbeddingModel(BaseModel):
    provider_name: str
    model_name: str

def get_embeddings(
    model: EmbeddingModel, 
    texts: list[str]
) -> dict[EmbeddingModel, list[float]]:
    # Implementation logic here

    return {}

```

### Error Handling Standards

Raise `OnyxError` instead of generic exceptions to ensure consistent JSON error payloads across the API. Import from `onyx.error_handling.exceptions` and use error codes from `onyx.error_handling.error_codes`.

```python
from onyx.error_handling.exceptions import OnyxError
from onyx.error_handling.error_codes import OnyxErrorCode

def fetch_document(doc_id: str):
    doc = db.get(doc_id)
    if doc is None:
        raise OnyxError(
            OnyxErrorCode.NOT_FOUND, 
            f"Document {doc_id} not found"
        )
    return doc

```

### PR Size Limits and Feature Flags

The repository enforces a **maximum 500-line change limit** per PR (see [`best_practices.md`](https://github.com/onyx-dot-app/onyx/blob/main/best_practices.md) lines 56‑58). For larger features, implement **trunk-based development** using feature flags from `onyx.feature_flags`:

```python
from onyx.feature_flags import is_enabled

if is_enabled("new_search"):
    # New logic implementation

    pass
else:
    # Fallback behavior

    pass

```

### Testing Requirements

Run the full test suite locally before submitting. The CI workflows in `.github/workflows/*.yml` will rerun these checks automatically.

```bash

# Unit tests

pytest -xv backend/tests/unit

# Integration tests (requires running services)

pytest -xv backend/tests/integration

```

## Submitting Your Pull Request

Follow the fork-and-PR workflow detailed in [`CONTRIBUTING.md`](https://github.com/onyx-dot-app/onyx/blob/main/CONTRIBUTING.md) (lines 18‑20):

1. **Fork** the repository on GitHub.
2. **Create a feature branch**: `git checkout -b feat/your-feature-name`.
3. **Commit** with clear, concise messages.
4. **Push** to your fork and open a PR against the `main` branch.
5. **Link the issue** in the PR description using `Fixes #123`.
6. **Address reviewer feedback** promptly and ensure all CI checks pass.

## Example: Adding a New Connector

Below is a compliant implementation of a fictional "ExampleDocs" connector demonstrating the required patterns:

```python

# backend/onyx/connectors/example_docs/fetcher.py

from typing import Iterable
from onyx.connectors.base import BaseConnector
from onyx.error_handling.exceptions import OnyxError
from onyx.error_handling.error_codes import OnyxErrorCode

class ExampleDocsFetcher(BaseConnector):
    """Stub connector demonstrating Onyx contribution standards."""

    def __init__(self, api_key: str):
        if not api_key:
            raise OnyxError(
                OnyxErrorCode.INVALID_ARGUMENT, 
                "API key required"
            )
        self.api_key = api_key

    def fetch_documents(self) -> Iterable[dict]:
        # Strictly typed return value

        yield {
            "title": "Hello World",
            "content": "Placeholder document from ExampleDocs.",
            "source_url": "https://example.com/doc/1",
        }

```

This example complies with guidelines by using `Iterable[dict]` typing, raising `OnyxError` for validation, and maintaining minimal file size suitable for a small PR. Add corresponding unit tests under `backend/tests/unit/connectors/example_docs/` and register the connector in [`backend/onyx/connectors/__init__.py`](https://github.com/onyx-dot-app/onyx/blob/main/backend/onyx/connectors/__init__.py).

## Summary

- **Get approval first**: Open a GitHub issue and obtain design sign-off before coding, especially for Enterprise features requiring the IP Assignment Agreement.
- **Follow strict standards**: Use mandatory Python typing, raise `OnyxError` for exceptions, and limit PRs to 500 lines of change.
- **Use feature flags**: Implement large changes behind flags from `onyx.feature_flags` to support trunk-based development.
- **Test thoroughly**: Run both unit and integration tests locally; CI workflows in `.github/workflows/` enforce these checks.
- **Submit properly**: Use the fork-and-PR workflow against `main`, link related issues, and respond to all review comments.

## Frequently Asked Questions

### Do I need to open an issue before contributing to Onyx?

Yes. The contribution process requires opening a GitHub issue to describe the problem and proposed solution. You must gather community up-votes and may need to submit a design document for review. This process is defined in [`contributing_guides/contribution_process.md`](https://github.com/onyx-dot-app/onyx/blob/main/contributing_guides/contribution_process.md) (lines 3‑24).

### What is the maximum PR size allowed in Onyx?

Pull requests must contain **no more than 500 lines of real change** as specified in [`contributing_guides/best_practices.md`](https://github.com/onyx-dot-app/onyx/blob/main/contributing_guides/best_practices.md) (lines 56‑58). Larger features should be split into smaller, incremental PRs or implemented behind feature flags using the `is_enabled` helper from `onyx.feature_flags`.

### How should I handle errors in Onyx code?

Always raise `OnyxError` instead of standard Python exceptions or `HTTPException`. Import `OnyxError` from `onyx.error_handling.exceptions` and use error codes from `onyx.error_handling.error_codes`. This ensures the global error handler produces consistent JSON payloads for API consumers.

### Do I need to sign an agreement to contribute Enterprise features?

Yes. Contributions to the Enterprise edition require signing the *IP Assignment Agreement* found in the `contributing_guides` folder. This is separate from the standard open-source contribution process and ensures proper intellectual property handling for commercial features.