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.
- 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.
cargo add rod-rsnpm install rod-jspip install rod-pyUses 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),
}
}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' }));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}")Rod prioritizes correctness and portability.
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.
- 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.
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 |
MIT © Yash Makan
