A high-performance, spec-correct JSON Schema validator written in C++
npm install ajv-cAJVC is a compiled, indexed-IR, tree-walking JSON Schema validation engine designed for production use in high-throughput, security-sensitive environments. It provides behavioral compatibility with AJV while delivering superior performance through native C++ compilation.
AJVC (Another JSON Schema Validator - C++) is a high-performance JSON Schema validator that compiles schemas into an optimized intermediate representation (IR) and validates JSON instances using an efficient tree-walking algorithm. Unlike interpreted validators, AJVC achieves peak performance immediately with no warmup time, no garbage collection pauses, and predictable memory usage.
While AJV is a widely-used JavaScript/TypeScript JSON Schema validator, AJVC distinguishes itself through:
- Compiled Performance: Native C++ implementation eliminates interpretation overhead, achieving validation times measured in nanoseconds per node
- No Runtime Overhead: No JIT warmup, no garbage collection, no VM pauses
- Memory Safety: Bounded allocations with RAII-based memory management
- Security Hardening: Built-in recursion depth limits, error limits, and $ref cycle detection to prevent denial-of-service attacks
- Thread Safety: Compiled schemas are immutable and can be safely shared across threads
- Deterministic Performance: Predictable execution time regardless of schema complexity
AJVC employs a three-phase architecture:
1. Schema Compilation: JSON Schema documents are parsed and compiled into an indexed intermediate representation (IR). The IR uses direct pointers to hot keywords (type, required, properties, items) for O(1) access, eliminating linear searches.
2. Indexed IR: The compiled schema uses indexed structures with pre-computed type sets, compiled regex patterns, and cached $ref resolutions. This enables efficient validation without repeated parsing or resolution.
3. Tree-Walking Validation: The validator traverses the JSON instance structure in tandem with the schema IR, applying keyword validators at each node. Boolean schema short-circuiting and early-exit optimizations minimize unnecessary work.
AJVC implements multiple safety mechanisms to prevent resource exhaustion and denial-of-service attacks:
- Recursion Depth Limits: Maximum schema validation depth of 256 levels (MAX_SCHEMA_DEPTH) prevents stack overflow from maliciously nested schemas
- $ref Depth Limits: Maximum $ref resolution depth of 64 levels (MAX_REF_DEPTH) prevents infinite reference chains
- Error Limits: Configurable maximum error count (default: 100) prevents unbounded error collection that could exhaust memory
- $ref Caching: Resolved $ref references are cached during compilation and reused during validation, preventing redundant resolution work
- Cycle Detection: Circular $ref references are detected and rejected during compilation
AJVC is engineered for high performance, achieving validation throughput measured in nanoseconds per schema node:
- Hot Path Performance: Simple type-only validations achieve ~50-80 nanoseconds per node
- Real-World Schemas: Complex schemas (OpenAPI, Stripe, GitHub webhooks) validate at ~200-300 nanoseconds per validation
- Adversarial Resilience: Even worst-case scenarios (deep allOf, wide oneOf) maintain reasonable performance with depth limits enforced
Benchmark results are available in docs/BENCHMARKING.md. The benchmark suite includes microbenchmarks, real-world schema tests, and adversarial scenarios.
- C++20 Compiler: GCC 10+, Clang 12+, or MSVC 2019+
- CMake: Version 3.20 or higher
- simdjson: Automatically fetched during build if not found
AJVC is available as a Node.js native addon package for use in Node.js applications.
``bash`
npm install ajvc
The package includes prebuilt binaries for:
- macOS: x64, arm64
- Linux: x64
- Windows: x64
If a prebuilt binary is not available for your platform, the package will automatically build from source during installation.
`javascript
const { validate } = require('ajvc');
// Validate with object inputs
const isValid1 = validate(
{ type: "number" },
5
);
console.log(isValid1); // true
const isValid2 = validate(
{ type: "number" },
"x"
);
console.log(isValid2); // false
// Validate with string inputs
const isValid3 = validate(
'{"type": "object", "properties": {"name": {"type": "string"}}, "required": ["name"]}',
'{"name": "John"}'
);
console.log(isValid3); // true
`
The package works with TypeScript. You can use it in TypeScript projects:
`typescript
import { validate } from 'ajvc';
const result: boolean = validate(
{ type: "string" },
"hello"
);
`
If you need to build from source (e.g., for a platform not covered by prebuilt binaries):
`bash`
npm install --build-from-source
This requires:
- Node.js 14.0.0 or higher
- Python 3 (for node-gyp)
- C++20 compiler (GCC 10+, Clang 12+, or MSVC 2019+)
- Build tools (make, cmake, etc.)
- simdjson: The build process will automatically fetch simdjson if CMake is available. Alternatively, you can install it system-wide:
- Linux: sudo apt-get install libsimdjson-dev (or equivalent)brew install simdjson
- macOS:
- Windows: Install via vcpkg or build from source
Note: Prebuilt binaries include simdjson statically linked, so no additional dependencies are needed when using prebuilt binaries.
`bash`
make build
For detailed build instructions, including dependency management, build options, and installation, see docs/BUILD.md.
`bash`
make test
The test suite includes:
- Unit tests for core functionality
- JSON Schema compliance tests
- AJV compatibility tests
- Edge case and regression tests
For detailed testing information, see docs/TESTING.md.
`bash`
make test_benchmark
The benchmark suite includes:
- Microbenchmarks for hot keyword performance
- Real-world schema validation tests
- Adversarial benchmarks for worst-case scenarios
- Regression detection to prevent performance degradation
Results are available in tests/bench/results/BENCHMARK_RESULTS.md.
For detailed benchmarking information, see docs/BENCHMARKING.md.
`cpp
#include
#include
int main() {
// Schema
std::string schema_json = R"({
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer", "minimum": 0}
},
"required": ["name"]
})";
// Instance
std::string instance_json = R"({
"name": "John",
"age": 30
})";
// Compile and validate
ajvc::SchemaCompiler compiler;
auto schema = compiler.compile(schema_json);
ajvc::Validator validator(std::make_shared
auto result = validator.validate(instance_json);
if (result.valid) {
std::cout << "Valid!" << std::endl;
} else {
std::cout << "Invalid: " << result.errors.first().message << std::endl;
}
return 0;
}
`
Run the example:
`bash``
make run
- Building AJVC - Build instructions, dependencies, and installation
- Testing AJVC - Test suite overview and writing new tests
- Benchmarking AJVC - Performance benchmarks and metrics
Contributions are welcome! Please read CONTRIBUTING.md for details on our code of conduct, development process, and pull request guidelines.
This project is licensed under the MIT License - see the LICENSE file for details.