The Problem
Centralized exchanges need high‑throughput matching engines, reliable persistence, and a clean API layer. Existing solutions often mix languages or lack clear boundaries between matching logic, persistence, and the network surface. This repo offers a Rust‑centric codebase split into domain, engine, cache, gateway, and worker modules, aiming to isolate concerns while exposing a single HTTP/WebSocket API.
What This Does
The project exposes a REST/WebSocket server (see apps/api) that forwards requests to the gateway crate (packages/gateway/src/lib.rs). Matching logic lives in the engine crate (packages/engine/src/lib.rs), while order persistence is handled by cache (packages/cache/src/lib.rs). Background workers (packages/workers) perform tasks such as snapshotting and event logging. Docker files (infra/kafka, infra/postgres, infra/redis) provide a ready‑to‑run environment.
How It Is Wired
Entry point: bin/server/src/main.rs.
main.rsloadsconfig.rs, creates a Tokio runtime, and callsspawner::spawn()to launch the API and background workers.spawner::spawn()starts thegatewayHTTP server and registers theworkersruntime.- Incoming HTTP requests hit
gateway::handlerswhich route togateway::exchange, a thin façade overengine::exchange. engine::exchangeprocesses orders viaengine::orderbook, emitting domain events (domain::events).- Domain events are pushed to Kafka by
queue::kafkaand cached in Redis bycache::lib. - The
workersmodule listens to the Kafka topic, executing eg.snapshot_workerto persist state to Postgres (infra/postgres/Dockerfile).
The call chain is linear: main -> spawner -> gateway -> engine -> domain events -> queue -> workers -> DB. The most central file is engine::exchange, as changes here ripple to order validation, matching, and event emission.
How To Use It
Setup
# clone
git clone https://github.com/moses-y/cex
# install Rust toolchain
rustup component add rustfmt
# install Node dependencies for the API
cd apps/api && pnpm install
Configuration Create .env from .env.example. Required variables are listed there (e.g., REDIS_URL, KAFKA_BOOTSTRAP_SERVERS, POSTGRES_URL).
Running
# start services
docker compose up -d
# launch the Rust server
cargo run --manifest-path bin/server/Cargo.toml
# API is reachable at http://localhost:3000
Real‑World Use
A trading firm can spin up the stack locally, publish orders via the API, and observe matching in real time. The gateway::handlers expose endpoints like /orders and /books. A quick example:
// Node client
import axios from 'axios';
await axios.post('http://localhost:3000/orders', {
symbol: 'BTCUSD',
side: 'buy',
qty: 1,
price: 50000
});
The order travels through the Rust engine, updates the in‑memory orderbook, and persists a snapshot after every batch.
Code Health & Issues
- Medium – No test files detected – the repository contains no
tests/directories or#[test]annotations. - Medium – No CI/CD pipeline – no
.github/or CI config files. - Medium – No LICENSE file – usage rights are unclear.
- Low – No documentation for API endpoints beyond the README; detailed contracts are missing.
The Bottom Line
The repo offers a modular, Rust‑based exchange skeleton with Docker‑ready infrastructure. It is a solid starting point for teams that can fill in tests, CI, and documentation. Without those, the codebase is difficult to ship or maintain at scale.