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:
| Variable | Description | Default |
|---|---|---|
VITE_MOCK_API | Enable mock API mode | false |
VITE_MOCK_SETUP_REQUIRED | Show the setup wizard instead of login | false |
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 clippybefore 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
- Review the Architecture documentation
- Check the API Documentation for endpoint details
- See Configuration for available options