JustAPI is a Python web framework with a Rust core. You write Python logic.
Rust handles everything else β networking, TLS, routing, validation,
serialization, SSE, database I/O, rate limiting. One pip install, a server
that starts in milliseconds, and numbers that hold up under real traffic.
Python writes the logic. Rust does everything else.
Quickstart
pip install justapi
# main.py
from justapi import JustAPIApp
app = JustAPIApp()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
app.run()
$ python main.py
INFO: JustAPI running on http://127.0.0.1:8000
Interactive OpenAPI docs at http://127.0.0.1:8000/docs β generated from your code, zero configuration.
Async? Native. DB? Native. SSE? Native.
import asyncio
from justapi import JustAPIApp, native_async
app = JustAPIApp()
app.set_database("postgres://user:pass@host/db")
app.sse_native("/events", count=1000, interval_ms=0) # Rust streams events β 0 Python per event
@app.get("/users/{uid}")
@native_async
async def get_user(request, uid: int):
row = await app.db.query_async( # runs on the DB's tokio runtime
"SELECT * FROM users WHERE id = ?", [uid]) # GIL released β loop never blocks
return row
app.run()
Performance
Hello-world, 100 concurrent connections, 30s, same hardware. Full methodology in BENCHMARKS.md.
| Framework | Hello-world | JSON echo | p99 hello-world | RSS |
|---|---|---|---|---|
| JustAPI (native fast path) | 766k req/s | 782k req/s | 0.48 ms | 12 MB |
| Granian (ASGI) | 314k | 145k | 0.74 ms | 37 MB |
| Robyn | 39k | β | β | β |
| FastAPI + Uvicorn | 36k | 33k | 24.63 ms | 29 MB |
More numbers, honestly:
- Route lookup: 51 ns average on a 500-route table (matchit radix trie)
- Rust-native CRUD: 181k SELECT req/s β Γ125 vs FastAPI on the same DB fixture
- Native async DB awaits (
query_async): 53Γ faster than the blocking path on slow queries (320 vs 6 RPS) β the asyncio loop is never blocked - Multi-worker prefork (
justapi serve --workers N): 1.88Γ throughput at 4 workers (99.7k RPS), auto-scale included - Free-threaded CPython (3.14t): CPU-bound Python handlers 12.4Γ faster β the GIL ceiling is gone
Honest caveats
- Native fast path requires a schema. Routes without a
Schemafall back to the Python handler path (~60k req/s). The ~700k numbers apply to routes withnative=True+Schema. - Python handler throughput is GIL-bound. On GIL-locked CPython, the Python dispatch path caps at ~100-120k req/s on this hardware regardless of framework β that is the GIL, not a framework limitation. Free-threaded Python (3.14t) removes this ceiling.
- Light async handlers are loop-bound. Async handlers that only sleep/echo (~4-12k req/s) are capped by the asyncio loop + thread hop. Three experiments (ADR-090/091/092) proved no coroutine driver, bridge, or multi-loop approach beats asyncio's own stepping. We win where it matters: real async workloads (1ms-sleep handlers: 3.9k vs Granian 2.9k RPS) and anything DB/SSE-heavy via native ops.
- LLM-serving claims are NOT part of this release. Inference phases are unverified (no real GPU run, ADR-067) β the tested story is the web framework.
How a request flows
The entire request path runs in Rust. Python executes only your application logic:
Kernel (epoll/io_uring)
β tokio connection manager
β TLS (rustls)
β HTTP parse (hyper)
β Router (matchit, 51ns)
β Middleware chain (auth, CORS, rate-limit, compression)
β Python boundary (zero-copy PyO3, GIL pool)
β Your async Python handler
β Rust serializer (serde_json / simd-json)
β Response write β socket
Routes marked native=True + Schema skip Python entirely β Rust validates the
body and writes the response. That is the ~700k req/s path.
Feature highlights
| Category | Feature | Details |
|---|---|---|
| Performance | HTTP/1.1 Β· HTTP/2 Β· HTTP/3 | ~766k req/s native fast path; QUIC (HTTP/3) is feature-gated β no other Python framework ships it |
| TLS (rustls) | ~10% overhead, zero OpenSSL dependency | |
| Serialization | serde_json with optional simd-json (89 ns/op) | |
| Compression | gzip / deflate / brotli / zstd | |
| Multi-worker prefork | justapi serve --workers N --scale β shared-socket process fleet with load-based auto-scaling | |
| Native ops | Async DB awaits | await app.db.query_async() β SQL on the DB's tokio runtime, GIL released, loop never blocked (ADR-093) |
| Rust-native CRUD | Rust validates + queries + serializes β 181k SELECT req/s, Γ125 vs FastAPI | |
| Native SSE | app.sse_native(path, count, interval_ms) β events generated in Rust, zero Python per event | |
| @native_async | Marks async handlers for the fastest dispatch; true parallel dispatch on free-threaded CPython | |
| Adaptive batching | Batch + window decorator for bursty workloads | |
| Security | JWT Authentication | HS256/RS256/ES256, per-route roles & scopes, OAuth2 password flow |
| Rate Limiting | GCRA, Redis-backed distributed, IP + per-route | |
| CORS | Configurable, preflight caching | |
| Request Validation | JSON Schema compiled in Rust, Pydantic v2 bridge | |
| Security Headers | HSTS, CSP, X-Frame-Options, nosniff, and more | |
| Protocols | REST | Full HTTP methods with OpenAPI 3.1 |
| WebSocket | Full-duplex with streaming support | |
| Server-Sent Events | Generator-driven + Rust-native streaming | |
| gRPC | Native Tonic integration | |
| GraphQL | async-graphql wiring | |
| Application | Dependency Injection | Litestar-style tiered DI, sync/async generators, cleanup |
| Background Tasks | Thread-safe task scheduling | |
| Database | SQLite / PostgreSQL / MySQL / DuckDB via sqlx β pool, migrations, transaction middleware | |
| Template Engine | Jinja2 integration | |
| File Uploads | Streaming multipart/form-data | |
| Operations | Observability | OpenTelemetry tracing, Prometheus metrics, health checks |
| Resilience | Circuit breakers, retry, fallback, bulkhead β 44 resilience tests | |
| Hot Reload | justapi serve --reload with graceful drain | |
| Plugin System | Third-party extension API with lifecycle hooks | |
| WASM Plugins | wasmtime-powered WebAssembly middleware | |
| DX & Quality | Type Stubs | py.typed + complete .pyi β mypy-clean on user code |
| Scaffolding | justapi create β full CRUD project (7 DB backends, 4 API styles) that demos every differentiator | |
| Memory Safety | ASan on the full suite + Miri on all unsafe code, 6 fuzz targets | |
| Supply Chain | cargo-deny β advisories, bans, licenses, sources |
Coming from FastAPI?
JustAPI mirrors FastAPI's decorator API and Pydantic integration, so existing
apps migrate with minimal changes β often just the import:
| FastAPI | JustAPI | |
|---|---|---|
| Import | from fastapi import FastAPI |
from justapi import JustAPIApp |
| Create | app = FastAPI() |
app = JustAPIApp() |
| Decorators | @app.get("/items/{id}") |
@app.get("/items/{id}") |
| Pydantic | Native | Native |
| Depends() | Built-in | Built-in (incl. generator deps + cleanup) |
| OpenAPI | /docs and /redoc |
/docs and /redoc |
| Server | uvicorn (Python) | Built-in Rust server (tokio + hyper) |
| Hello-world | ~36k req/s | ~766k req/s (native fast path) |
π Full migration guide.
Architecture
justapi/
βββ crates/
β βββ justapi-core/ # Networking, routing, middleware, serialization
β βββ justapi-py/ # PyO3 bindings + Python package (python/justapi)
β βββ justapi-cli/ # CLI binary (serve, create, check, gen-client)
β βββ justapi-bench/ # Internal benchmark harness
βββ assets/ # README diagrams (animated SVG)
βββ benchmarks/ # Workload scripts for baseline comparisons
βββ docs_site/ # Full documentation site (141 pages)
βββ skills/ # Reusable engineering knowledge
βββ PLAN.md # Living roadmap (single source of truth)
βββ DECISIONS.md # Append-only ADR log
βββ BENCHMARKS.md # Append-only performance ledger
Crate dependency graph:
justapi-cli βββ justapi-core
justapi-py βββ justapi-core
justapi-bench ββ justapi-core
Development
Prerequisites
- Rust 1.85+ β install via rustup
- Python 3.11+ β download
- maturin β
pip install maturin
Build & test
cargo build --workspace --release
cd crates/justapi-py && maturin develop --release # build the Python package
cargo test --workspace # Rust tests
cargo clippy --workspace --tests -- -D warnings # lint
cargo fmt --check # format
cargo deny check # supply-chain audit
bash scripts/sanitize.sh # ASan + Miri memory-safety gate
python -m pytest # Python tests (in the venv)
Benchmark
bash benchmarks/run_baselines.sh # FastAPI / Granian / JustAPI A/B
See BENCHMARKS.md for methodology, hardware, and history.
Deployment
# Docker (multi-stage, uv-based β fast reproducible builds)
docker build -t justapi-app .
docker run -p 8000:8000 justapi-app
# Multi-worker + auto-scale (saturate all cores)
justapi serve --workers 4 --scale
- Kubernetes:
helm install my-api helm/justapi/ --set image.repository=your-registry/justapi-app - Cloud guides: EKS Β· GKE Β· AKS Β· Fly.io Β· Railway
- Observability: OTel tracing + Prometheus metrics + health probes out of the box
Documentation
| Document | Description |
|---|---|
| docs_site | Full documentation site β 141 pages, 13 sections, search |
| Migration guide | Step-by-step from FastAPI |
| BENCHMARKS.md | Performance ledger (append-only) |
| PLAN.md | Living roadmap and current phase |
| DECISIONS.md | Architecture decision records (ADR-001 β ADR-093) |
| AGENTS.md | Development conventions & review checklist |
Contributing
Contributions welcome. Read AGENTS.md for conventions before opening a PR.
git clone [email protected]:swadhinbiswas/JustAPI.git
cd JustAPI
git checkout -b feat/my-feature
# ... make changes ...
cargo test --workspace
cargo clippy --workspace --tests -- -D warnings
cargo fmt --check
Every PR is gated on: tests green, clippy -D warnings, fmt clean, sanitizers
clean (core touched), benchmarks appended (perf touched), ADR recorded
(architecture touched).
License
MIT Β© JustAPI contributors