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
Release files for rod-py 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rod_py-0.1.1.tar.gz | 34.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rod_py-0.1.1-cp312-cp312-macosx_11_0_arm64.whl | CPython 3.12 | CPython 3.12 | macOS 11.0+ ARM64 | Details |
Total release size: 956.8 kB
Release files / rod_py-0.1.1.tar.gz
| Download URL | rod_py-0.1.1.tar.gz |
|---|---|
| Size | 34.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a10b6d59932b6e76f3ec533a5c10d35f50cb28663e513fe78292886cdce6ecd9
|
|
BLAKE2b-256 checksum How to use checksums |
fab3395213550a391264e9fae77536fcb45b4e52422d271d20a2926c4c6f0792
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.11.5
|
Release files / rod_py-0.1.1-cp312-cp312-macosx_11_0_arm64.whl
| Download URL | rod_py-0.1.1-cp312-cp312-macosx_11_0_arm64.whl |
|---|---|
| Size | 921.9 kB |
| Tags | CPython 3.12 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
29a2b087dd677ceb0a083e1563d8d591eeb6784d0cc9b3e128a927e5771672f6
|
|
BLAKE2b-256 checksum How to use checksums |
2991585e42f55cc1b97bed42c9b5f262b5756d4f10381bd2d86eda92998fed1a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.11.5
|