AnyVali logo AnyVali

Portable validation without the extra layer

Native schemas. Cross-language contracts.

Author with a native SDK, export a canonical schema document, and validate consistently across runtimes.

  • Native builder APIs in each SDK
  • Portable JSON interchange with strict semantics
  • Shared conformance corpus across languages
  • Full type inference in TypeScript with Infer<T>, generics in all SDKs

Migration demo

One schema, different SDKs

Python author + export + import
schema = v.object({ "id": v.int64(), "email": v.string().format("email"), }) result = schema.safe_parse({ "id": 42, "email": "team@anyvali.dev", }) print(schema.export()) # portable contract # same JSON document every time imported_schema = v.import_schema(schema.export()) imported_result = imported_schema.safe_parse({ "id": 42, "email": "team@anyvali.dev", }) schema := v.Object(v.Fields{ "id": v.Int64(), "email": v.String().Format("email"), }) result := schema.SafeParse(map[string]any{ "id": 42, "email": "team@anyvali.dev", }) doc, _ := schema.Export(v.ExportPortable) // portable contract // same JSON document every time imported, _ := v.ImportSchema(doc) roundTrip := imported.SafeParse(map[string]any{ "id": 42, "email": "team@anyvali.dev", }) const schema = v.object({ id: v.int64(), email: v.string().format("email"), }); const result = schema.safeParse({ id: 42, email: "team@anyvali.dev", }); console.log(schema.export()); // portable contract // same JSON document every time const importedSchema = importSchema(schema.export()); const importedResult = importedSchema.safeParse({ id: 42, email: "team@anyvali.dev", }); var schema = V.object(Map.of( "id", V.int64(), "email", V.string().format("email") )); var result = schema.safeParse(Map.of( "id", 42, "email", "team@anyvali.dev" )); System.out.println(schema.export()); // portable contract // same JSON document every time var imported = importSchema(schema.export()); var importedResult = imported.safeParse(Map.of( "id", 42, "email", "team@anyvali.dev" )); var schema = V.Object(new Dictionary<string, Schema> { { "id", V.Int64() }, { "email", V.String().Format("email") }, }); var result = schema.SafeParse(new Dictionary<string, object> { { "id", 42 }, { "email", "team@anyvali.dev" }, }); Console.WriteLine(schema.Export()); // portable contract // same JSON document every time var imported = ImportSchema(schema.Export()); var importedResult = imported.SafeParse(new Dictionary<string, object> { { "id", 42 }, { "email", "team@anyvali.dev" }, }); let schema = v::object(fields![ "id" => v::int64(), "email" => v::string().format("email"), ]); let result = schema.safe_parse(json!({ "id": 42, "email": "team@anyvali.dev" })); println!("{}", schema.export()); // portable contract // same JSON document every time let imported = import_schema(schema.export()); let imported_result = imported.safe_parse(json!({ "id": 42, "email": "team@anyvali.dev" })); $schema = v\object([ "id" => v\int64(), "email" => v\string()->format("email"), ]); $result = $schema->safeParse([ "id" => 42, "email" => "team@anyvali.dev", ]); echo json_encode($schema->export()); // portable contract // same JSON document every time $imported = import_schema($schema->export()); $importedResult = $imported->safeParse([ "id" => 42, "email" => "team@anyvali.dev", ]); schema = AnyVali.object({ "id" => AnyVali.int64, "email" => AnyVali.string.format("email"), }) result = schema.safe_parse({ "id" => 42, "email" => "team@anyvali.dev", }) puts schema.export # portable contract # same JSON document every time imported = AnyVali.import_schema(schema.export) imported_result = imported.safe_parse({ "id" => 42, "email" => "team@anyvali.dev", }) val schema = V.obj(mapOf( "id" to V.int64(), "email" to V.string().format("email"), )) val result = schema.safeParse(mapOf( "id" to 42, "email" to "team@anyvali.dev", )) println(schema.export()) // portable contract // same JSON document every time val imported = importSchema(schema.export()) val importedResult = imported.safeParse(mapOf( "id" to 42, "email" to "team@anyvali.dev", )) auto schema = v::object({ { "id", v::int64() }, { "email", v::string().format("email") }, }); auto result = schema.safe_parse({ { "id", 42 }, { "email", "team@anyvali.dev" }, }); std::cout << schema.export(); // portable contract // same JSON document every time auto imported = import_schema(schema.export()); auto imported_result = imported.safe_parse({ { "id", 42 }, { "email", "team@anyvali.dev" }, });

Native-first, not JSON-first

AnyVali is meant to feel familiar if you use Zod, Valibot, or the validation layer of your own platform. You keep authoring in the host language instead of dropping into a neutral DSL.

Portability with boundaries

Portable core features move cleanly between SDKs. Local-only behavior stays local. That split is explicit, which keeps your shared contracts honest instead of silently drifting.

Deterministic parse semantics

The pipeline is defined: presence, coercion, defaults, validation, output. Teams can reason about what happens in every runtime without reverse-engineering edge cases.

How it works

Schema authoring that survives language boundaries

01

Define locally

Use the SDK API that fits your language conventions.

02

Export canonically

Emit a versioned JSON document with definitions and extensions.

03

Import elsewhere

Load the same contract in another AnyVali SDK.

04

Validate consistently

Rely on the same issue codes, coercions, defaults, and constraints.

Examples

Fast, readable authoring across SDKs

TypeScript

const Account = v.object({
  id: v.int64(),
  plan: v.enum(["free", "pro"]),
  email: v.string().format("email"),
});

Python

account = v.object({
    "id": v.int64(),
    "plan": v.enum(["free", "pro"]),
    "email": v.string().format("email"),
})

Go

account := v.Object(v.Fields{
    "id": v.Int64(),
    "plan": v.Enum("free", "pro"),
    "email": v.String().Format("email"),
})
Explore deeper examples

Use cases

Built for teams that cross service, client, and language boundaries

Frontend to backend contracts

Author in TypeScript, validate in Go or Java without rewriting schema logic.

Schema registries

Store exported JSON documents and let any AnyVali runtime import them on demand.

Polyglot platforms

Keep consistency when services evolve independently but still share data contracts.

SDK families

Back every implementation with the same conformance corpus and issue model.

SDK coverage

One model, multiple ecosystems

JavaScript / TypeScriptIn repo
PythonIn repo
GoIn repo
JavaIn repo
C#In repo
RustIn repo
PHPIn repo
RubyIn repo
KotlinIn repo
C++In repo

Learn more

Specification, portability, and implementation details

Use the docs for the normative spec, JSON format, portability rules, and SDK guidance.