Development
This guide covers building Codex from source for development purposes.
Prerequisites
- Rust 1.92 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.
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/
├── src/
│ ├── api/ # HTTP API handlers
│ ├── commands/ # CLI commands
│ ├── config/ # Configuration management
│ ├── db/ # Database layer
│ ├── parsers/ # File format parsers
│ ├── scanner/ # File scanning logic
│ └── utils/ # Utility functions
├── migration/ # Database migrations
├── tests/ # Integration tests
└── docs/ # Documentation
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