Skip to main content

Project Structure

Understanding how Ryx is organized will help you navigate the codebase and contribute effectively.

High-Level Layoutโ€‹

Ryx/
โ”œโ”€โ”€ Cargo.toml # Workspace configuration
โ”œโ”€โ”€ pyproject.toml # maturin build config
โ”œโ”€โ”€ Makefile # Dev shortcuts (dev, build, test, clean)
โ”‚
โ”œโ”€โ”€ ryx-core/ # CORE TYPES (Rust)
โ”‚ โ””โ”€โ”€ src/ # Connection/Transaction enums, Base types
โ”‚
โ”œโ”€โ”€ ryx-backend/ # DB ADAPTERS (Rust)
โ”‚ โ””โ”€โ”€ src/ # Executor, RowView, Decoding logic
โ”‚
โ”œโ”€โ”€ ryx-query/ # SQL COMPILER (Rust)
โ”‚ โ””โ”€โ”€ src/ # AST, Compiler, Lookup registry
โ”‚
โ”œโ”€โ”€ ryx-python/ # PyO3 BINDINGS (Rust)
โ”‚ โ””โ”€โ”€ src/ # Module entry, Type bridge, Bound objects
โ”‚
โ”œโ”€โ”€ ryx/ # PYTHON PACKAGE
โ”‚ โ”œโ”€โ”€ __init__.py # Public API surface
โ”‚ โ”œโ”€โ”€ __main__.py # CLI (python -m ryx)
โ”‚ โ”œโ”€โ”€ models.py # Model, Metaclass, Manager
โ”‚ โ”œโ”€โ”€ queryset.py # QuerySet, Q, aggregates
โ”‚ โ”œโ”€โ”€ fields.py # 30+ field types
โ”‚ โ”œโ”€โ”€ validators.py # 12 validators
โ”‚ โ”œโ”€โ”€ signals.py # Signal system + 8 built-in signals
โ”‚ โ”œโ”€โ”€ transaction.py # Async transaction context manager
โ”‚ โ”œโ”€โ”€ relations.py # select_related / prefetch_related
โ”‚ โ”œโ”€โ”€ descriptors.py # FK/M2M attribute access
โ”‚ โ”œโ”€โ”€ exceptions.py # Exception hierarchy
โ”‚ โ”œโ”€โ”€ bulk.py # Bulk operations
โ”‚ โ”œโ”€โ”€ cache.py # Pluggable query cache
โ”‚ โ””โ”€โ”€ migrations/
โ”‚ โ”œโ”€โ”€ state.py # SchemaState + diff engine
โ”‚ โ”œโ”€โ”€ ddl.py # Backend-aware DDL generator
โ”‚ โ”œโ”€โ”€ runner.py # MigrationRunner
โ”‚ โ””โ”€โ”€ autodetect.py # Autodetector + file writer
โ”‚
โ”œโ”€โ”€ tests/ # Test suites
โ””โ”€โ”€ examples/ # 9 progressive examples

Two Layers, One Packageโ€‹

Ryx is split into two layers that work together:

Rust Engine (Workspace)โ€‹

The compiled engine is split into specialized crates for maintainability:

  • ryx-core โ€” Defines the foundational types and traits.
  • ryx-query โ€” Transforms Python-like queries into optimized SQL.
  • ryx-backend โ€” Handles database communication and zero-allocation row decoding.
  • ryx-python โ€” The PyO3 bridge that exposes Rust logic to Python.

Python Package (ryx/)โ€‹

The ergonomic API that handles:

  • Model definitions โ€” Declarative class-based models with metaclass magic
  • Query building โ€” Chainable, lazy QuerySet API
  • Field types โ€” 30+ fields with validation and type conversion
  • Migrations โ€” Schema introspection, diff detection, DDL generation
  • Signals โ€” Observer pattern for lifecycle events
  • CLI โ€” Management commands for migrations, shell, etc.

How They Connectโ€‹

# Python side
posts = await Post.objects.filter(active=True).limit(10)
โ”‚
โ–ผ
# QuerySet builds a QueryNode (Python โ†’ Rust via PyO3)
โ”‚
โ–ผ
# Rust compiles QueryNode โ†’ SQL
# SELECT * FROM "posts" WHERE "active" = ? LIMIT 10
โ”‚
โ–ผ
# Rust executes via sqlx and returns rows
โ”‚
โ–ผ
# Python decodes rows into Model instances

Key Design Principlesโ€‹

  1. Immutable builders โ€” Every QuerySet method returns a new QuerySet
  2. GIL minimization โ€” Rust holds no GIL during SQL execution
  3. Async-native โ€” Everything is async from the ground up
  4. Sync-compatible โ€” Bridge helpers for sync environments
  5. Backend-agnostic โ€” Single code path for PG, MySQL, SQLite

Next Stepsโ€‹

โ†’ Models โ€” Define your first models โ†’ Rust Core Internals โ€” Deep dive into the compiled engine