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

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 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 (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 and contributing_guides/dev_setup.md.

Development Environment Setup

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

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."

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.

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 lines 56‑58). For larger features, implement trunk-based development using feature flags from onyx.feature_flags:

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.


# 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 (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:


# 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.

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 (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 (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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →