A high-performance schema validation library for Python, powered by Rust.
Project description
Rod
The Write-Once, Validate-Anywhere Schema Library.
Rod is a high-performance schema validation engine powered by Rust. It compiles to native binaries, WebAssembly (Node.js/Browser), and Python extensions, allowing you to enforce the exact same validation logic across your entire stack.
Stop rewriting regexes in three different languages. Define it once in Rod, run it everywhere.
🚀 Key Features
- Unified Logic: A
uuid()check in the browser uses the exact same byte-level logic as your Rust backend. No more "Schema Drift." - Zero-Copy Architecture: Rod validates data directly in the host language's memory (V8 Heap, Python Objects, or Rust Structs) without expensive intermediate serialization.
- Fluent API: A chainable builder pattern (
rod.string().min(5)) familiar to Zod/Pydantic users. - Batch Optimization: Specialized bitmask APIs for validating massive datasets (100k+ items) with minimal FFI overhead.
📦 Installation
Rust
cargo add rod-rs
JavaScript / TypeScript
npm install rod-js
Python
pip install rod
⚡ Quick Start
1. Rust
Uses the rod_obj! macro for cleaner syntax.
use rod_rs::{rod_obj, string, number, RodValidator};
use serde_json::json;
fn main() {
// Define schema using the macro
let user_schema = rod_obj! {
name: string().min(3),
email: string().email(),
age: number().int().min(18.0)
};
// Data (e.g., from an API request)
let data = json!({
"name": "Rod",
"email": "hi@rod.rs",
"age": 25
});
// Zero-copy wrap & validate
let input = rod_rs::io::json::wrap(&data);
match user_schema.validate(&input) {
Ok(_) => println!("✅ Valid!"),
Err(e) => println!("❌ Error: {:?}", e.issues),
}
}
2. TypeScript
Requires a one-time WASM initialization.
import { rod } from 'rod-js';
await rod.init(); // Initialize WASM
const User = rod.object({
name: rod.string().min(3),
email: rod.string().email(),
tags: rod.array(rod.string()).min(1)
}).strict();
const data = {
name: "Rod",
email: "hi@rod.rs",
tags: ["wasm", "rust"]
};
// 'lazy' mode reads fields on-demand without full serialization
console.log(User.parse(data, { mode: 'lazy' }));
3. Python
Native extension via PyO3.
import rod
User = rod.object({
"name": rod.string().min(3),
"email": rod.string().email(),
"tags": rod.array(rod.string()).min(1)
}).strict()
data = {
"name": "Rod",
"email": "hi@rod.rs",
"tags": ["ffi", "rust"]
}
try:
print(User.parse(data))
except ValueError as e:
print(f"Validation failed: {e}")
📊 Performance & Architecture
Rod prioritizes correctness and portability.
The "Bridge Tax"
Rod runs inside a Rust core. When used from JS or Python, there is an overhead to cross the language boundary (Foreign Function Interface).
- Simple Objects: For tiny objects (e.g.,
{ a: 1 }), native libraries like Zod (JS) or Pydantic (Python) are faster because they don't pay the FFI tax. - Complex Logic: For heavy validation (UUIDs, huge arrays, complex regex), Rod often outperforms native JS/Python logic.
- Native Rust: Rod is blazingly fast (~200ns per object), comparable to raw handwritten Rust checks.
Recommendation
- Use Rod when you need strict consistency between Backend/Frontend, or when processing batch data.
- Use Zod/Pydantic if you are writing a single-language app and don't need shared logic.
🛠 Development
This is a monorepo managed by just.
| Command | Description |
|---|---|
just build-all |
Build Rust core, WASM bindings, and Python extension |
just test-all |
Run integration tests across all three languages |
just bench-all |
Run comparative benchmarks against Zod and Pydantic |
📄 License
MIT © Yash Makan
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rod_py-0.1.1.tar.gz.
File metadata
- Download URL: rod_py-0.1.1.tar.gz
- Upload date:
- Size: 34.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.11.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a10b6d59932b6e76f3ec533a5c10d35f50cb28663e513fe78292886cdce6ecd9
|
|
| MD5 |
891f0b77d3277119493698685aa09905
|
|
| BLAKE2b-256 |
fab3395213550a391264e9fae77536fcb45b4e52422d271d20a2926c4c6f0792
|
File details
Details for the file rod_py-0.1.1-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: rod_py-0.1.1-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 921.9 kB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.11.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
29a2b087dd677ceb0a083e1563d8d591eeb6784d0cc9b3e128a927e5771672f6
|
|
| MD5 |
29c750d4ac98b4a170c1d1ea83466be2
|
|
| BLAKE2b-256 |
2991585e42f55cc1b97bed42c9b5f262b5756d4f10381bd2d86eda92998fed1a
|