Contributing
This guide covers everything you need to set up a bext development environment, run the test suite, and submit changes.
Prerequisites
| Tool | Version | Notes |
|---|---|---|
| Rust | 1.80+ (stable) | Install via rustup |
| Bun | 1.1+ | Required for JS integration tests and site development |
| Git | 2.30+ | |
| Linux | Recommended | Full feature testing requires kernel 5.15+ (eBPF, nsjail) |
Optional (for specific features):
| Tool | Feature | Notes |
|---|---|---|
| PHP 8.2+ | php feature |
Compiled with --enable-embed --enable-zts |
| Redis 7+ | redis feature |
For L2 cache and realtime relay tests |
| Docker | Container tests | For container-based integration testing |
| MaxMind GeoIP DB | WAF geo tests | GeoLite2-Country database |
| wasm32-wasi target | WASM plugin tests | rustup target add wasm32-wasi |
Getting Started
git clone https://github.com/bext-dev/bext.git
cd bext
Build the community edition (fastest)
cargo build -p bext-server
Build with all features
cargo build -p bext-server --all-features
Build a release binary
cargo build --release -p bext-server
The release profile uses opt-level = 3, fat LTO, single codegen unit, and symbol stripping. Expect ~3 minutes for a full-featured release build on an M2 MacBook Pro.
Project Structure
bext/
Cargo.toml # Workspace root
crates/ # Rust library and binary crates (16 crates)
harnesses/ # Conformance, ecosystem, and security test suites
companion/ # Desktop companion app (Tauri + Svelte)
sites/ # bext.dev ecosystem sites (docs, blog, main, etc.)
docs/ # Internal platform documentation
See Architecture Overview for the full crate dependency graph.
Running Tests
Unit tests (all crates)
cargo test --workspace
Unit tests for a specific crate
cargo test -p bext-core
cargo test -p bext-plugin-api
cargo test -p bext-waf
cargo test -p bext-license
Tests with all features enabled
cargo test --workspace --all-features
This is needed for WAF, plugin, eBPF, and PHP tests since those modules are behind feature flags.
Specific test
cargo test -p bext-license -- roundtrip_early_bird --nocapture
Integration tests
# Next.js conformance suite
cargo test -p conformance
# Framework ecosystem tests (requires Bun + Node)
cd harnesses/ecosystem && bun test
# Security / fuzzing harness
cargo test -p security
Plugin sandbox tests
# QuickJS plugin tests
cargo test -p bext-plugin-quickjs
# WASM plugin tests (requires wasm32-wasi target)
cargo test -p bext-plugin-wasm
# nsjail plugin tests (Linux only)
cargo test -p bext-plugin-nsjail
Code Organization
The workspace follows a strict layering discipline:
1. Leaf crates (bext-plugin-api, bext-license) have no bext dependencies and minimal external dependencies. They define traits and types.
2. Feature crates (bext-tls, bext-waf, bext-realtime, bext-ebpf, bext-php, bext-plugin-*) implement specific features. They may depend on leaf crates.
3. Core crate (bext-core) contains shared business logic. It depends on leaf crates but not on feature crates (except via Cargo features).
4. Binary crates (bext-server, bext-keygen, bext-nginx-shim) wire everything together. They depend on all other crates via feature flags.
When adding new code, place it in the lowest appropriate layer. If a type needs to be shared between feature crates, put it in bext-plugin-api or bext-core.
Code Style
- Run cargo fmt before committing.
- Run cargo clippy --workspace --all-features and fix all warnings.
- Follow existing patterns in the crate you are modifying.
- Add doc comments (/// or //!) to all new public types, functions, and modules.
- bext has 2,500+ tests -- add tests for any new functionality.
Commit Message Format
Follow conventional commits:
feat(waf): add custom rule DSL for request matching
Add a declarative rule format that lets users define WAF rules
in bext.config.toml without writing Rust code.
Closes #142
Prefixes: feat, fix, docs, refactor, test, perf, ci, chore.
The scope in parentheses should be a crate name or area (e.g., waf, cache, render, cli, docs, plugin-quickjs).
Pull Request Guidelines
1. One concern per PR -- do not mix a bug fix with a feature.
2. Add tests for any new behavior.
3. Update docs if you are changing user-facing behavior.
4. Run the full test suite before pushing: cargo test --workspace --all-features.
5. Keep PRs small -- under 500 lines changed when possible.
Checklist before submitting
- [ ] cargo test --workspace --all-features passes
- [ ] cargo clippy --workspace --all-features -- -D warnings reports no warnings
- [ ] cargo fmt --check passes
- [ ] New public types have doc comments
- [ ] Feature-gated code uses #[cfg(feature = "...")] correctly
- [ ] No new dependencies added without justification in the PR description
Review process
1. Open a PR against master.
2. CI runs the full pipeline (see below).
3. One maintainer approval required for merge.
4. Squash merge is the default. Use merge commits only for large feature branches with meaningful intermediate commits.
Adding a New Feature Flag
If your contribution adds a new optional subsystem:
1. Create the crate in crates/bext-your-feature/.
2. Add the dependency as optional in crates/bext-server/Cargo.toml:
bext-your-feature = { path = "../bext-your-feature", optional = true }
3. Define the feature in [features]:
[features]
your-feature = ["dep:bext-your-feature"]
4. Guard initialization with #[cfg(feature = "your-feature")] in main.rs and any modules that reference the crate.
5. Add a license feature name in crates/bext-license/src/tier.rs.
6. Add the feature to the appropriate tier's feature list (Community, Pro, or Enterprise).
7. Add a cargo_feature_to_license mapping.
8. Run the tier superset tests: cargo test -p bext-license.
CI Pipeline
Every PR runs:
| Job | What it does | Duration |
|---|---|---|
fmt |
cargo fmt --check |
~5s |
clippy |
cargo clippy --workspace --all-features -- -D warnings |
~2 min |
test |
cargo test --workspace --all-features |
~4 min |
build |
cargo build --release -p bext-server |
~3 min |
conformance |
Next.js spec tests against bext-server | ~3 min |
ecosystem |
Integration tests for Next.js, Hono, Express, Laravel, Symfony, PHP | ~5 min |
security |
Sandbox escape tests + short fuzzing run | ~2 min |
Release builds additionally produce binaries for Linux (x86_64, aarch64) and macOS (aarch64).
Debugging Tips
Enable trace logging
RUST_LOG=bext_server=trace,bext_core=debug cargo run
Profile a specific transform
cargo test -p bext-core transform::barrel_optimize -- --nocapture
Inspect plugin sandbox activity
BEXT_PLUGIN_LOG=trace cargo run --features plugins
Run a single conformance test
cargo test -p conformance test_name -- --nocapture
Getting Help
- Issues: github.com/bext-dev/bext/issues
- Discussions: github.com/bext-dev/bext/discussions