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).
- Create a GitHub issue describing the problem, proposed solution, and any architectural considerations.
- Gather community interest through up-votes. If the issue stalls for more than one week, you may email
yuhong@onyx.appfor reviewer attention. - Complete design review if requested by the core team. For Enterprise-edition contributions, you must sign the IP Assignment Agreement located in the
contributing_guidesfolder.
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):
- Fork the repository on GitHub.
- Create a feature branch:
git checkout -b feat/your-feature-name. - Commit with clear, concise messages.
- Push to your fork and open a PR against the
mainbranch. - Link the issue in the PR description using
Fixes #123. - 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
OnyxErrorfor exceptions, and limit PRs to 500 lines of change. - Use feature flags: Implement large changes behind flags from
onyx.feature_flagsto 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →