Skip to main content

AnyVali

AnyVali

Native validation libraries for 10 languages, one portable schema model.

CI codecov License: MIT npm PyPI crates.io Go NuGet Gem

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

PHP uses a pinned Composer source installation.

npm install anyvali          # JavaScript / TypeScript
pip install anyvali           # Python
go get github.com/BetterCorp/AnyVali/sdk/go  # Go
cargo add anyvali             # Rust
dotnet add package AnyVali    # C#
# PHP: pinned Composer source installation (see installation link above)
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 / TypeScriptPython
import { string, int, object, array } from "anyvali";

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)
    }
}

Type Inference

All 10 SDKs now provide static type inference, so parsed values carry the correct type without manual casts. The TypeScript SDK offers full Zod-style Infer<T>:

import { object, string, int, type Infer } from "anyvali";

const User = object({
  name: string().minLength(1),
  email: string().format('email'),
  age: int().min(0).optional(),
});

type User = Infer<typeof User>;
// => { name: string; email: string; age?: number | undefined }

const user = User.parse(input); // fully typed, no cast needed

Other SDKs use the type inference mechanism native to each language:

  • Python -- BaseSchema(Generic[T]), ParseResult(Generic[T]); parse() returns T
  • C# / Kotlin -- Schema<T> generic base class, ParseResult<T>
  • Java -- Schema<T> generic base, ParseResult<T> record
  • Go -- TypedParse[T]() and TypedSafeParse[T]() generic helper functions
  • Rust -- TypedSchema trait with associated Output type, parse_as<T>() free function
  • C++ -- Template parse_as<T>() and safe_parse_as<T>() helpers
  • PHP -- @template phpDoc annotations for PHPStan/Psalm
  • Ruby -- RBS type signature file for Steep/Sorbet

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!

Sensitive Data

Mark secrets with sensitive: true, then supply your own encryption function. AnyVali validates before and after transformation but never ships encryption logic or keys.

import { decrypt, encrypt, object, safeParseEncrypted, string } from "anyvali";

const Credentials = object({
  username: string(),
  password: string().minLength(12).describe("Password", { sensitive: true }),
});

const stored = encrypt(Credentials, input, (path, value) =>
  `encrypted:${encryptWithYourKms(path, value)}`,
);

safeParseEncrypted(Credentials, stored); // validates the encrypted storage shape

const clear = decrypt(Credentials, stored, (path, value) =>
  decryptWithYourKms(path, value.slice("encrypted:".length)),
);

Sensitive objects and arrays are encrypted as one opaque value. See the sensitive data guide for behavior, security boundaries, and every SDK's API names.

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";
import { initForm } from "anyvali/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";
import { createFormBindings } from "anyvali/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": "strip"
  },
  "definitions": {},
  "extensions": {}
}

Supported SDKs

Language Package Status
JavaScript / TypeScript anyvali 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 from source Pinned repository release
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.


anyvali.com

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

anyvali-1.1.6.tar.gz (32.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

anyvali-1.1.6-py3-none-any.whl (41.7 kB view details)

Uploaded Python 3

File details

Details for the file anyvali-1.1.6.tar.gz.

File metadata

  • Download URL: anyvali-1.1.6.tar.gz
  • Upload date:
  • Size: 32.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for anyvali-1.1.6.tar.gz
Algorithm Hash digest
SHA256 aedee3dbeefe78aee1183d7041f59b83618bdf934744c25fa105514b3ea565c6
MD5 29ddc9071449d0fb3e764f49a4a5b185
BLAKE2b-256 e6f63f6349ae49f062a442e85383b6962c333bdc32e11c66308cfe03db6fc923

See more details on using hashes here.

Provenance

The following attestation bundles were made for anyvali-1.1.6.tar.gz:

Publisher: build-release.yml on BetterCorp/AnyVali

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file anyvali-1.1.6-py3-none-any.whl.

File metadata

  • Download URL: anyvali-1.1.6-py3-none-any.whl
  • Upload date:
  • Size: 41.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for anyvali-1.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 a27319dc103e384732ddd6175e0858b6b5a0f9c7d30d63d788a417552ea815eb
MD5 a1be1eb35b24a2a151244cdf71060b8e
BLAKE2b-256 321a9b29b4303e950f26e8fcacfc994731daa0f321b9407f11b6c3ef8d3002d3

See more details on using hashes here.

Provenance

The following attestation bundles were made for anyvali-1.1.6-py3-none-any.whl:

Publisher: build-release.yml on BetterCorp/AnyVali

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.1.6 This release

2 files

1.1.5

2 files

1.1.4

2 files

1.1.3

2 files

1.1.2

2 files

1.1.1

2 files

1.1.0

2 files

1.0.7

2 files

1.0.6

2 files

1.0.5

2 files

1.0.4

2 files

1.0.3

2 files

0.2.6

2 files

0.2.4

2 files

0.2.3

2 files

0.0.5

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page