Skip to main content

Development

This guide covers building Codex from source for development purposes.

Prerequisites

  • Rust 1.93 or later
  • Cargo (comes with Rust)
  • OpenSSL development libraries
  • UnRAR library (optional, for CBR support)

Installing Rust

If you don't have Rust installed, use rustup:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Installing System Dependencies

macOS

brew install openssl

Ubuntu/Debian

sudo apt-get update
sudo apt-get install build-essential pkg-config libssl-dev

Fedora/RHEL

sudo dnf install gcc openssl-devel

Building from Source

Clone the Repository

git clone https://github.com/AshDevFr/codex.git
cd codex

Install Pre-commit Hooks

After cloning, install pre-commit hooks to ensure generated files stay in sync:

make setup-hooks

This requires Python and will install pre-commit if not already available. The hooks ensure that web/openapi.json and web/src/types/api.generated.ts are regenerated when backend API changes are committed.

Standard Build (with CBR support)

By default, Codex includes CBR support:

cargo build --release

The binary will be located at target/release/codex.

Build without CBR Support

If you want to avoid the proprietary UnRAR dependency:

cargo build --release --no-default-features

This disables CBR parsing but keeps all other formats (CBZ, EPUB, PDF) working.

Development Build

For faster iteration during development:

cargo build

This creates an unoptimized binary at target/debug/codex that compiles faster.

Running Tests

All Tests

cargo test

Specific Test Suites

# Parser tests
cargo test parsers

# Database tests
cargo test db

# API tests
cargo test api

Tests without CBR Support

cargo test --no-default-features

PostgreSQL Integration Tests

For running PostgreSQL tests, start the test container with make test-up and run make test-postgres.

Fast Parallel Tests (cargo-nextest)

For significantly faster test execution, install cargo-nextest:

cargo install cargo-nextest --locked

Then run tests with:

# Fast parallel tests
make test-fast

# Fast PostgreSQL tests
make test-fast-postgres

Nextest runs tests in parallel and is typically 2-3x faster than cargo test.

Speeding Up Builds

Codex's .cargo/config.toml is preconfigured to use faster linkers and (optionally) a compilation cache. Installing these tools will noticeably reduce rebuild times during development.

Faster Linker

On a typical Apple Silicon machine, lld cuts warm rebuild link time by roughly a third (e.g., ~23s instead of ~35s) compared to the system linker. On Linux, mold provides a similar improvement.

macOS

brew install lld

Linux

# Ubuntu/Debian
sudo apt-get install mold clang

# Fedora
sudo dnf install mold clang

If the linker is not installed, Cargo falls back to the default linker automatically (no errors), so this step is optional.

Compilation Cache (sccache)

sccache caches compiled crates across cargo clean, branch switches, and changes to Cargo.lock. It mainly helps cold builds and dependency recompiles; it adds ~2s of wrapper overhead on warm incremental rebuilds, but the cold-build savings (around 10% on this project) typically outweigh that.

Install it:

# macOS
brew install sccache

# Linux / other
cargo install sccache --locked

sccache is opt-in per developer. The repo's .cargo/config.toml deliberately doesn't wire it in, so checkouts work on machines and in CI/Docker environments where it isn't installed. Pick whichever opt-in fits your setup:

# Shell profile (applies to every cargo project on your machine)
export RUSTC_WRAPPER=sccache
# Or in ~/.cargo/config.toml (user-level, also applies everywhere)
[build]
rustc-wrapper = "sccache"

To disable temporarily for a single build, prefix it with RUSTC_WRAPPER= cargo build.

Check the cache hit rate at any time:

sccache --show-stats

macOS: Exclude target/ from Spotlight

The target/ directory can grow to many gigabytes with thousands of small files. Spotlight indexing those files causes very high system CPU during builds. Exclude the directory:

touch target/.metadata_never_index

Or add target/ to System Settings → Siri & Spotlight → Spotlight Privacy. The Privacy entry is path-based and survives cargo clean.

Verify Setup

Check that your development tools are properly installed:

make dev-check

This will show which optional performance tools are available.

Development Workflow

Running the Server

# Development mode (with debug logging)
RUST_LOG=debug cargo run -- serve --config config/config.sqlite.yaml

Hot Reload (Docker)

Use Docker Compose with watch mode for automatic rebuilds:

docker compose -f docker-compose.yml -f compose.watch.yml --profile dev up --watch

Frontend Development

For full-stack development with the React frontend:

# Start backend and frontend (recommended)
docker compose --profile dev up

# Access the app at http://localhost:5173
# The Vite dev server proxies /api and /opds requests to the backend

Or run them separately:

# Terminal 1 - Backend
cargo run -- serve --config config/config.sqlite.yaml

# Terminal 2 - Frontend
cd web
npm install
npm run dev

# Access at http://localhost:5173

Important: Always use http://localhost:5173 (frontend) in development. The Vite dev server automatically proxies API requests to the backend at http://localhost:8080.

The frontend is a React/TypeScript application using Vite, Mantine UI, and TanStack Query.

Mock API Mode

For frontend-only development without a backend, you can use the mock API:

cd web
VITE_MOCK_API=true npm run dev

Environment variables for mock mode:

VariableDescriptionDefault
VITE_MOCK_APIEnable mock API modefalse
VITE_MOCK_SETUP_REQUIREDShow the setup wizard instead of loginfalse

Example to test the setup wizard:

VITE_MOCK_API=true VITE_MOCK_SETUP_REQUIRED=true npm run dev

Code Formatting

cargo fmt

Linting

cargo clippy

Project Structure

Codex is a Cargo workspace. The top-level binary crate (src/) is intentionally thin; the bulk of the code lives in sibling crates under crates/. Editing one subsystem only recompiles that crate and its downstream consumers, which keeps warm rebuilds fast.

codex/
├── src/ # codex (binary) crate
│ ├── main.rs # CLI entry point
│ └── commands/ # Per-subcommand orchestration (scan, serve, ...)
├── crates/
│ ├── codex-api/ # HTTP API: axum routes, OPDS, Komga, observability
│ ├── codex-config/ # YAML config + env overrides
│ ├── codex-db/ # SeaORM entities + repositories
│ ├── codex-events/ # In-process event broadcaster
│ ├── codex-models/ # Cross-layer DTOs and shared types
│ ├── codex-parsers/ # CBZ/CBR/EPUB/PDF parsing
│ ├── codex-scanner/ # Library scan workflow
│ ├── codex-scheduler/ # Cron/interval scheduler
│ ├── codex-search/ # In-memory fuzzy search index
│ ├── codex-services/ # Business logic (auth, plugins, metadata, ...)
│ ├── codex-tasks/ # Background worker + task handlers
│ └── codex-utils/ # Crypto, JWT, hashing, error types
├── migration/ # SeaORM migrations (own crate, used by codex-db)
├── tests/ # Integration tests against codex-api
└── docs/ # Documentation

Per-crate builds work in isolation, e.g. cargo build -p codex-parsers.

Database Migrations

Running Migrations

Migrations run automatically on server startup. To run manually:

cd migration
cargo run

Creating New Migrations

Use SeaORM's migration CLI:

# Install migration CLI
cargo install sea-orm-cli

# Create new migration
sea-orm-cli migrate generate <migration_name>

Contributing

Code Style

  • Follow Rust standard formatting (cargo fmt)
  • Run cargo clippy before submitting PRs
  • Write tests for new features

Testing

  • Add unit tests for new functions
  • Add integration tests for API endpoints
  • Ensure all tests pass before submitting

Documentation

  • Update relevant documentation when adding features
  • Add code comments for complex logic
  • Update API documentation if endpoints change

Debugging

Enable Debug Logging

RUST_LOG=debug codex serve --config codex.yaml

Database Debugging

For SQLite, you can inspect the database directly:

sqlite3 data/codex.db

For PostgreSQL:

psql -U codex -d codex

Tracing

Codex uses the tracing crate for structured logging. Set log levels:

RUST_LOG=codex=debug,tower_http=info codex serve

Performance Profiling

Release Build

Always profile with release builds:

cargo build --release

Profiling Tools

  • perf (Linux): perf record ./target/release/codex serve
  • Instruments (macOS): Use Xcode Instruments
  • flamegraph: Generate flamegraphs for performance analysis

Next Steps