# rjson

> Fast JSON library for Python (PyPI: `pyrjson`, import: `rjson`), written in Rust against the CPython C API. An alternative to orjson and the standard library `json`: faster than orjson on most workloads (geomean `loads` 1.17×, `dumps` 1.36× on the reference benchmark; 21 of 22 production-shaped workloads, 1.52×), with byte-identical output to `orjson.dumps`. CPython 3.10–3.14, Linux (glibc, musl), macOS, Windows. MIT license. Status: 0.x, pin the version.

Install with `pip install pyrjson` (not `rjson`, an unrelated package), then `import rjson`.

API:
- `rjson.loads(data, *, lenient=False)`: `data` is `str`, `bytes`, `bytearray` or `memoryview`. `lenient=True` accepts exactly what `json.loads` accepts (NaN/Infinity, BOM, lone surrogates).
- `rjson.dumps(obj, *, default=None, passthrough=0, non_str_keys=False, indent=None, sort_keys=False) -> bytes`: UTF-8, same bytes as `orjson.dumps(obj)`; `indent=2`/`sort_keys=True` match orjson's `OPT_INDENT_2`/`OPT_SORT_KEYS`. Serializes `datetime`, `date`, `time`, `uuid.UUID`, dataclasses and `Enum` natively.
- `rjson.dumps_str(...) -> str`: same JSON as a `str` (like `json.dumps(obj, ensure_ascii=False, separators=(",", ":"))`).
- `rjson.JSONDecodeError` is `json.JSONDecodeError`; `rjson.JSONEncodeError` subclasses both `TypeError` and `ValueError`.
- `passthrough=rjson.PASSTHROUGH_DATETIME | ...` corresponds to orjson's `OPT_PASSTHROUGH_*`; `non_str_keys=True` to `OPT_NON_STR_KEYS`.

Migrating code (find-and-replace):
- `orjson.loads(x)` / `json.loads(x)` → `rjson.loads(x)`
- `orjson.dumps(x)` → `rjson.dumps(x)`; `orjson.dumps(x).decode()` → `rjson.dumps_str(x)`
- `json.dumps(x).encode()` → `rjson.dumps(x)`
- `orjson.dumps(x, default=f)` → `rjson.dumps(x, default=f)`
- `orjson.dumps(x, option=OPT_INDENT_2 | OPT_SORT_KEYS)` → `rjson.dumps(x, indent=2, sort_keys=True)` (same bytes); `json.dumps(x, indent=4, sort_keys=True)` → `rjson.dumps_str(x, indent=4, sort_keys=True)`
- Not supported yet: orjson's other `option=` flags (`OPT_SERIALIZE_NUMPY`, `OPT_APPEND_NEWLINE`, `OPT_OMIT_MICROSECONDS`, ...); NaN/Infinity in `dumps` raise. Not supported: PyPy, free-threaded CPython builds. Keep orjson or `json` for those calls.

## Docs

- [README](https://github.com/TinDang97/rjson/blob/main/README.md): usage, full API table, migration guide, FastAPI integration, FAQ
- [Showcase: rjson vs orjson](https://github.com/TinDang97/rjson/blob/main/docs/SHOWCASE.md): 22 production-shaped workloads, method, and where rjson is not faster
- [Production readiness](https://github.com/TinDang97/rjson/blob/main/docs/PRODUCTION_READINESS.md): workloads, memory, migration blockers
- [Async and threads](https://github.com/TinDang97/rjson/blob/main/docs/ASYNC.md): asyncio, uvloop, thread guidance
- [Changelog](https://github.com/TinDang97/rjson/blob/main/CHANGELOG.md)

## Examples

- [Faster JSON in Python services](https://github.com/TinDang97/rjson/blob/main/docs/guides/faster-json-in-python-services.md): FastAPI, logging, NDJSON and Redis/Kafka patterns with measured speedups vs json and orjson
- [FastAPI response and request integration](https://github.com/TinDang97/rjson/blob/main/examples/fastapi_app.py)
- [Examples index: logging/NDJSON, Redis/Kafka codec](https://github.com/TinDang97/rjson/blob/main/examples/README.md)

## Optional

- [Performance review and roadmap](https://github.com/TinDang97/rjson/blob/main/docs/PERFORMANCE_REVIEW.md)
- [Security policy](https://github.com/TinDang97/rjson/blob/main/SECURITY.md)
- [Type stub](https://github.com/TinDang97/rjson/blob/main/rjson.pyi)
