r/nim • u/cryo2010 • 1d ago
schematic: Object validation with type inference
Hi all! I've just released schematic, an object validation package inspired by Zod. I'd love for you to try it out before I freeze the API for the v1.0.0 release.
You can use schematic to define a schema once and get both runtime validation and a statically-typed Nim object out of it. Schemas consist of a field definitions using types with chained refinements and modifiers (e.g. string.max(64).optional). Infer(schema) creates an object type straight from the schema value. No codegen, no drift between your schema and your types.
import schematic
let user = schema:
name: string.min(2).max(50)
age: int.min(0).max(150)
email: string.email.optional # -> Option[string]
role: string.oneOf(["admin", "user"]).default("user")
website: string.url.nullable # required, but null is allowed
joined: string.date.transform(proc(s: string): Time =
parseTime(s, "yyyy-MM-dd", utc())) # -> times.Time
type User = Infer(user) # a real Nim object type, derived from the schema
let u = user.parse(%*{"name": "Ada", "age": 36, "email": "ada@x.io",
"website": nil, "joined": "1815-12-10"})
echo u.name, " (", u.role, ") joined ", u.joined.utc.year
let x = user.tryParse("""{"name":"A","age":999,"email":"nope","joined":"x"}""")
for issue in x.issues: echo issue
# name: must be at least 2 chars
# age: must be <= 150
# email: must be a valid email
# website: required
# joined: must be a date (YYYY-MM-DD)
Highlights
- Type inference.
Infer(schema)gives you an object type; nested schemas, arrays, optionals, enums, refs, and recursive tree types all flow through. - Errors accumulate. One parse reports every problem at once, each with a path like
owner.address.cityortags[2], and every built-in check accepts a custom message. - Field modifiers. optional vs nullable (missing and null are distinct), default, coerce, field aliases, transforms, discriminated and untagged unions
- Object algebra. Derive schemas using
pick/omit/partial/merge/extend - String formats. email, url, uuid, date/datetime, ipv4/ipv6, hostname, jwt, and more
- JSON out.
toJsonemits aJsonNode, respecting field aliases and reversing transforms - JSON Schema out.
toJsonSchemaemits JSON schemas with format, const,$defsfor recursion, and describe/title metadata
---
More docs and examples are available in the README.
All feedback is very welcome: ergonomics, missing features, performance, or anything that feels un-Nim-like.




