Native validation with portable schema interchange
Project description
AnyVali
Native validation libraries for 10 languages, one portable schema model.
Website · Docs · Issues · Contributing
AnyVali lets you write validation schemas in your language, then share them across any of 10 supported runtimes via a portable JSON format. Think Zod, but for every language.
Why AnyVali?
- Write schemas natively -- idiomatic APIs for each language, not a separate DSL
- Share across languages -- export to JSON, import in any other SDK
- Safe numeric defaults --
number= float64,int= int64 everywhere - Deterministic parsing -- coerce, default, then validate, in that order
- Conformance tested -- shared test corpus ensures identical behavior across SDKs
Install
npm install @anyvali/js # JavaScript / TypeScript
pip install anyvali # Python
go get github.com/BetterCorp/AnyVali/sdk/go # Go
cargo add anyvali # Rust
dotnet add package AnyVali # C#
composer require anyvali/anyvali # PHP
gem install anyvali # Ruby
Java / Kotlin / C++
Java (Maven)
<dependency>
<groupId>com.anyvali</groupId>
<artifactId>anyvali</artifactId>
<version>0.0.1</version>
</dependency>
Kotlin (Gradle)
implementation("com.anyvali:anyvali:0.0.1")
C++ (CMake)
FetchContent_Declare(anyvali GIT_REPOSITORY https://github.com/BetterCorp/AnyVali)
FetchContent_MakeAvailable(anyvali)
target_link_libraries(your_target PRIVATE anyvali)
Quick Start
Define a schema, parse input, get structured errors or clean data.
| JavaScript / TypeScript | Python |
|---|---|
import { string, int, object, array } from "@anyvali/js";
const User = object({
name: string().minLength(1),
email: string().format('email'),
age: int().min(0).optional(),
tags: array(string()).maxItems(5),
});
// Throws on failure
const user = User.parse(input);
// Or get a result object
const result = User.safeParse(input);
if (!result.success) {
console.log(result.issues);
}
|
import anyvali as v
User = v.object_({
"name": v.string().min_length(1),
"email": v.string().format("email"),
"age": v.int_().min(0).optional(),
"tags": v.array(v.string()).max_items(5),
})
# Raises on failure
user = User.parse(input_data)
# Or get a result object
result = User.safe_parse(input_data)
if not result.success:
print(result.issues)
|
Go example
import av "github.com/BetterCorp/AnyVali/sdk/go"
User := av.Object(map[string]av.Schema{
"name": av.String().MinLength(1),
"email": av.String().Format("email"),
"age": av.Optional(av.Int().Min(0)),
"tags": av.Array(av.String()).MaxItems(5),
})
result := User.SafeParse(input)
if !result.Success {
for _, issue := range result.Issues {
fmt.Printf("[%s] %s at %v\n", issue.Code, issue.Message, issue.Path)
}
}
Cross-Language Schema Sharing
AnyVali's core feature: export a schema from one language, import it in another.
// TypeScript frontend -- export
const doc = User.export();
const json = JSON.stringify(doc);
// Send to your backend, save to DB, put in a config file...
# Python backend -- import
import json, anyvali as v
schema = v.import_schema(json.loads(schema_json))
result = schema.safe_parse(request_body) # Same validation rules!
Forms
The JS SDK also ships a small forms layer for browser-native fields, HTML5 attributes, and AnyVali validation.
import { object, string, int } from "@anyvali/js";
import { initForm } from "@anyvali/js/forms";
const Signup = object({
email: string().format("email"),
age: int().min(18),
});
initForm("#signup", { schema: Signup });
<form id="signup">
<input name="email" type="email" />
<input name="age" type="number" />
<button type="submit">Create account</button>
</form>
For JSX-style attribute binding:
import { object, string } from "@anyvali/js";
import { createFormBindings } from "@anyvali/js/forms";
const Signup = object({
email: string().format("email"),
});
const form = createFormBindings({ schema: Signup });
<input {...form.field("email")} />;
The portable JSON format:
{
"anyvaliVersion": "1.0",
"schemaVersion": "1",
"root": {
"kind": "object",
"properties": {
"name": { "kind": "string", "minLength": 1 },
"email": { "kind": "string", "format": "email" }
},
"required": ["name", "email"],
"unknownKeys": "reject"
},
"definitions": {},
"extensions": {}
}
Supported SDKs
| Language | Package | Status |
|---|---|---|
| JavaScript / TypeScript | @anyvali/js |
v0.0.1 |
| Python | anyvali |
v0.0.1 |
| Go | github.com/BetterCorp/AnyVali/sdk/go |
v0.0.1 |
| Java | com.anyvali:anyvali |
v0.0.1 |
| C# | AnyVali |
v0.0.1 |
| Rust | anyvali |
v0.0.1 |
| PHP | anyvali/anyvali |
v0.0.1 |
| Ruby | anyvali |
v0.0.1 |
| Kotlin | com.anyvali:anyvali |
v0.0.1 |
| C++ | anyvali (CMake) |
v0.0.1 |
CLI & HTTP API
Don't need an SDK? Use AnyVali from the command line or as a validation microservice.
# Validate from the command line
anyvali validate schema.json '{"name": "Alice", "email": "alice@test.com"}'
# Pipe from stdin
cat payload.json | anyvali validate schema.json -
# Start a validation server
anyvali serve --port 8080 --schemas ./schemas/
# Validate via HTTP
curl -X POST http://localhost:8080/validate/user \
-H "Content-Type: application/json" \
-d '{"name": "Alice", "email": "alice@test.com"}'
Pre-built binaries for Linux, macOS, and Windows are available on the releases page. Docker image: docker pull anyvali/cli.
See the CLI Reference and HTTP API Reference for full documentation.
Schema Types
| Category | Types |
|---|---|
| Primitives | string, bool, null |
| Numbers | number (float64), int (int64), float32, float64, int8-int64, uint8-uint64 |
| Special | any, unknown, never |
| Values | literal, enum |
| Collections | array, tuple, object, record |
| Composition | union, intersection |
| Modifiers | optional, nullable |
Documentation
| Guide | Description |
|---|---|
| Getting Started | Installation, API reference, examples |
| Numeric Semantics | Why number = float64 and int = int64 |
| Portability Guide | Design schemas that work across all languages |
| SDK Authors Guide | Implement a new AnyVali SDK |
| Canonical Spec | The normative specification |
| JSON Format | Interchange format details |
| CLI Reference | Command-line validation tool |
| HTTP API | Validation microservice / sidecar |
| Development | Building, testing, contributing |
Repository Layout
.
├── docs/ Documentation guides
├── spec/ Canonical spec, JSON format, conformance corpus
├── sdk/
│ ├── js/ JavaScript / TypeScript SDK
│ ├── python/ Python SDK
│ ├── go/ Go SDK
│ ├── java/ Java SDK
│ ├── csharp/ C# SDK
│ ├── rust/ Rust SDK
│ ├── php/ PHP SDK
│ ├── ruby/ Ruby SDK
│ ├── kotlin/ Kotlin SDK
│ └── cpp/ C++ SDK
├── cli/ CLI binary and HTTP API server (Go)
├── runner.sh Build/test/CI runner
└── site/ anyvali.com source
Contributing
Contributions are welcome. Please read CONTRIBUTING.md before opening a pull request.
./runner.sh help # See all commands
./runner.sh test js # Test a specific SDK
./runner.sh ci # Run the full CI pipeline locally
pwsh -File tools/release/build_release.ps1 # Build release artifacts with Docker
License
AnyVali is licensed under the MIT License.
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 anyvali-0.0.5.tar.gz.
File metadata
- Download URL: anyvali-0.0.5.tar.gz
- Upload date:
- Size: 24.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
186e62a888ead9e0ff2662728f1bdf031d35e0fa5642190906e796c546dae465
|
|
| MD5 |
a8ddab070924ae63a749f60340aca014
|
|
| BLAKE2b-256 |
e5ccb5e466ac64b0b67784952e2dced57dd8f1c8928cf41a9b2e4879ebefd027
|
Provenance
The following attestation bundles were made for anyvali-0.0.5.tar.gz:
Publisher:
release-pypi.yml on BetterCorp/AnyVali
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anyvali-0.0.5.tar.gz -
Subject digest:
186e62a888ead9e0ff2662728f1bdf031d35e0fa5642190906e796c546dae465 - Sigstore transparency entry: 1197046107
- Sigstore integration time:
-
Permalink:
BetterCorp/AnyVali@eb1a50061269b7d1f40d857b027e287e4ba21374 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/BetterCorp
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@eb1a50061269b7d1f40d857b027e287e4ba21374 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file anyvali-0.0.5-py3-none-any.whl.
File metadata
- Download URL: anyvali-0.0.5-py3-none-any.whl
- Upload date:
- Size: 33.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e689c56d66c184bb5f4bbc91a5439ecfe4ec0500878e9e0892e53960ea2a547c
|
|
| MD5 |
ecd9f500891aea2395e5e245da7c0cf9
|
|
| BLAKE2b-256 |
e1639f3611fe042bf2481f157f014b9ccd11bdf80295d36bcaa51f4fb1082d8c
|
Provenance
The following attestation bundles were made for anyvali-0.0.5-py3-none-any.whl:
Publisher:
release-pypi.yml on BetterCorp/AnyVali
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anyvali-0.0.5-py3-none-any.whl -
Subject digest:
e689c56d66c184bb5f4bbc91a5439ecfe4ec0500878e9e0892e53960ea2a547c - Sigstore transparency entry: 1197046169
- Sigstore integration time:
-
Permalink:
BetterCorp/AnyVali@eb1a50061269b7d1f40d857b027e287e4ba21374 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/BetterCorp
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@eb1a50061269b7d1f40d857b027e287e4ba21374 -
Trigger Event:
workflow_dispatch
-
Statement type: