Thank you for your interest in contributing to AISIX! This guide covers everything you need to set up a development environment, follow project conventions, and submit contributions.
- Prerequisites
- Setting Up the Development Environment
- Configuration
- Project Structure
- Building
- Running Tests
- Code Style
- Commit Guidelines
- Submitting a Pull Request
- CI/CD
- Security
- License
Install the following before starting:
| Tool | Version | Notes |
|---|---|---|
| Rust | latest stable | Install via rustup |
| Node.js | LTS | Used for the admin UI |
| pnpm | (bundled) | corepack enable pnpm after Node.js install |
| Docker & Docker Compose | any recent | Required for etcd and test services |
| protobuf-compiler | any | Required to build Rust gRPC dependencies |
Install system dependencies (Ubuntu/Debian):
sudo apt update
sudo apt install -y protobuf-compiler docker.io docker-compose-v2
corepack enable pnpmgit clone https://github.com/api7/aisix.git
cd aisixdocker compose -f ci/docker-compose.yaml up -d etcdTo run E2E tests, use
docker compose -f ci/docker-compose.yaml up -dto bring up all required services.
pnpm -C ui install --frozen-lockfile
pnpm -C ui buildThe UI build output is embedded into the Rust binary at compile time via rust-embed.
Tip: For UI-only development, run
pnpm -C ui devto start a hot-reload dev server that proxies API calls to the running gateway.
RUST_LOG=info cargo runThe gateway starts two servers:
- Proxy API on
0.0.0.0:3000— OpenAI-compatible endpoint for LLM requests - Admin API on
127.0.0.1:3001— manages models, API keys, and the playground
The gateway reads config.yaml at startup (pass --config <path> to use a different file):
deployment:
etcd:
host:
- "http://127.0.0.1:2379"
prefix: /aisix
timeout: 30
admin:
admin_key:
- key: admin # Admin API key — change for production
server:
proxy:
listen: 0.0.0.0:3000
tls:
enabled: false
cert_file: cert.pem
key_file: key.pem
admin:
listen: 127.0.0.1:3001src/
├── main.rs # Entry point, server setup
├── lib.rs # Library exports
├── admin/ # Admin API (port 3001)
├── config/ # Configuration loading and etcd provider
├── providers/ # AI provider implementations (OpenAI, Anthropic, Gemini, DeepSeek)
├── proxy/ # Proxy API (port 3000) — handlers, middlewares, hooks
└── utils/ # Shared utilities
ui/ # React admin UI (Vite + TanStack Router/Query)
tests/
├── api.rs # Rust integration test entry point
├── admin/ # Admin API tests
├── proxy/ # Proxy tests
├── utils/ # Test helpers
└── e2e/ # TypeScript E2E tests (Vitest)
# Debug build (faster compile, slower runtime)
cargo build
# Release build
cargo build --releaseMake sure etcd is running before starting:
# Run all tests
cargo test
# Run a specific test file
cargo test --test api
# Run a specific test by name
cargo test test_crud
# Run tests in a specific module
cargo test --test admin::models_api
# Show println!/dbg! output
cargo test -- --nocaptureThe E2E test suite runs the gateway binary directly — it requires:
- A built binary at
target/debug/aisix - etcd and other required services running (
ci/docker-compose.yaml)
# Build the binary first
cargo build
# Install E2E test dependencies
pnpm -C tests install --frozen-lockfile
# Run E2E tests
pnpm -C tests testpnpm -C ui lint # ESLint
pnpm -C ui typecheck # TypeScript type check (no emit)Format: Run cargo fmt before every commit. CI rejects unformatted code.
cargo fmt # Format all Rust code
cargo fmt -- --check # Verify formatting without changesLint: Fix all Clippy warnings — they are treated as errors in CI:
cargo clippy --all-targets --all-features --locked -- -D warningsImport order (enforced by rustfmt.toml):
// 1. Standard library
use std::sync::Arc;
// 2. External crates (alphabetical)
use anyhow::Result;
use axum::{Json, extract::State};
use serde::{Deserialize, Serialize};
// 3. Local modules
use crate::config::entities::Model;Naming conventions:
| Item | Convention | Example |
|---|---|---|
| Types / Structs / Enums | PascalCase |
ProviderConfig |
| Functions / Methods | snake_case |
chat_completions |
| Constants / Statics | SCREAMING_SNAKE_CASE |
MODELS_PATTERN |
| Modules | snake_case |
chat_completions |
Error handling:
- Use
thiserrorfor domain/library errors - Use
anyhowfor application-level errors - Axum handler errors must implement
IntoResponse
Async:
- Runtime:
tokio - Async trait methods require
#[async_trait] - Async tests use
#[tokio::test]
Tracing: Annotate handler and provider functions with #[fastrace::trace].
pnpm -C ui format # Prettier (writes)
pnpm -C ui lint # ESLintFollow Conventional Commits:
<type>: <subject>
<body>
Types: feat, fix, docs, refactor, test, chore, ci
Rules:
- Subject line: imperative mood, concise description
- Body: bullet points explaining what changed and why (optional for trivial changes)
- Do not add
Co-authored-by:trailers - Do not add attribution links
Examples:
feat: add rate limiting per API key
- Implement concurrent and token-per-minute limits
- Store rate limit state in DashMap for lock-free access
fix: handle empty etcd prefix in config loader
- Fork the repository and create a branch from
main. - Make your changes following the code style guidelines above.
- Run the full verification suite locally before pushing:
cargo fmt -- --check cargo clippy --all-targets --all-features --locked -- -D warnings cargo test
cargo build && pnpm -C tests install --frozen-lockfile && pnpm -C tests test
4. Commit using Conventional Commits format.
5. Open a pull request against `main`. Describe **why** the change is needed, not just what it does.
6. CI runs automatically on every PR — all checks must pass before merging.
---
## CI/CD
The GitHub Actions workflow (`.github/workflows/build.yaml`) runs on every push and PR to `main`:
| Step | Command |
|------|---------|
| Build UI | `pnpm -C ui install --frozen-lockfile && pnpm -C ui build` |
| Lint | `cargo clippy --all-targets --all-features --locked -- -D warnings` |
| Test | `cargo test --verbose` |
| E2E Test | `pnpm -C tests install --frozen-lockfile && pnpm -C tests test` |
| Build | `cargo build --verbose` |
The CI environment uses `ci/docker-compose.yaml` to start etcd and other required services.
---
## Security
If you discover a security vulnerability, please **do not** open a public GitHub issue.
Follow the process described in [SECURITY.md](./SECURITY.md) to report it privately.
---
## License
By contributing, you agree that your contributions will be licensed under the [Apache License 2.0](LICENSE).