jsonschema

A compliant, dependency-light Go library for compiling and validating JSON Schema across five draft versions, with rich hierarchical errors.

Library
Go
vv5.3.1
1,264stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
64/100Good
Development Activity60
Maintenance44
Community52
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
76/100Good
Architecture82
Code Quality78
Innovation68
Learning Curve75

jsonschema is a Go library that compiles JSON Schema documents into an introspectable, thread-safe *Schema value and validates arbitrary JSON against it. It supports draft-4 through draft 2020-12 in a single compiler, auto-detecting the draft from a schema’s $schema property or falling back to a configurable default, so a single codebase can validate schemas written against different spec generations.

The library is built to pass the official JSON-Schema-Test-Suite (with only a documented set of optional cases excluded), which makes it one of the more spec-faithful Go implementations available. It resolves remote and recursive references, detects infinite reference loops before they become stack overflows, and supports draft 2019-09/2020-12 features like $recursiveRef, $dynamicRef, unevaluatedProperties, and unevaluatedItems.

Validation failures come back as a ValidationError with a full cause hierarchy addressable via JSON Pointers into both the schema and the instance document, and can be rendered as flag, basic, or detailed output per the JSON Schema output spec. A companion jv CLI (versioned independently under cmd/jv) wraps the same compiler for validating JSON or YAML files from the command line, including over HTTP(S) schema URLs.

The package name here — github.com/santhosh-tekuri/jsonschema/v5 — is the v5 major-version import path; the same repository has since moved on to a v6 module (import path .../jsonschema/v6) with a different public API, so projects pinned to v5 should treat this as a stable, frozen line rather than the latest release.

What You Get

  • A Compiler type that parses and compiles JSON Schema documents from file paths, HTTP(S) URLs, strings, byte slices, or io.Reader, resolving $refs (including remote and recursive references) along the way
  • Automatic draft detection from a schema’s $schema property (draft-4, draft-6, draft-7, draft 2019-09, draft 2020-12), with an explicit Compiler.Draft override when $schema is absent
  • A fully introspectable compiled *Schema struct exposing every keyword (types, properties, pattern properties, conditionals, numeric bounds, etc.) as public fields, useful for building tools like schema-to-struct generators
  • Rich ValidationError values with a causal hierarchy and JSON-Pointer locations in both the schema and the instance document, plus FlagOutput(), BasicOutput(), and DetailedOutput() renderers matching the JSON Schema spec’s output formats
  • Support for user-defined format validators, content encodings/media types, and custom resource loaders, plus a keyword-extension mechanism for adding vocabulary beyond the spec
  • An independently versioned jv command-line tool (cmd/jv) that validates JSON or YAML documents against a schema, with configurable draft and output format flags

Common Use Cases

  • Validating API request/response bodies against a JSON Schema in a Go HTTP service before further processing
  • Enforcing configuration file correctness at startup by compiling a schema once and validating parsed YAML/JSON config against it
  • Building developer tooling — e.g. generating Go structs or documentation from a compiled schema by walking its introspectable Schema fields
  • Running jv in CI to lint JSON/YAML fixtures or generated artifacts against a schema without writing any Go code
  • Cross-checking schemas that mix draft versions (via remote $refs) in one validation pass, since the compiler resolves each referenced resource against its own declared draft

Under The Hood

Architecture The library separates schema compilation from validation into two dense but distinct files: compiler.go walks a raw map[string]interface{} document and progressively fills a *Schema struct (schema.go) field by field, guarded by draft-version checks (r.draft.version >= N) and vocabulary checks (r.schema.meta.hasVocab("applicator")) so a single compiler correctly supports five spec generations without branching into five code paths. $ref/$recursiveRef/$dynamicRef resolution happens through a resource abstraction (root.go, roots.go) that tracks per-document base URLs and a stack []schemaRef used by checkLoop to detect infinite reference cycles before they blow the Go call stack. Validation (in validate) walks the compiled *Schema tree directly against a decoded interface{} value, threading an unevalProps/unevalItems result struct through nested calls so unevaluatedProperties/unevaluatedItems (added in later drafts) can see what sibling keywords already accounted for. The core abstraction change that would ripple furthest is the compiled Schema struct itself — it’s deliberately public and exhaustive, which is what enables the introspection use case but means any new keyword must be added there plus threaded through both compileMap and validate.

Tech Stack Pure Go with a minimal dependency footprint: go.mod declares only golang.org/x/text (Unicode/text processing, likely for the hostname/IDNA-related format validators) as a runtime dependency, plus github.com/dlclark/regexp2 as a test-only dependency for exercising ECMA-style regex behavior. Numeric validation uses math/big.Rat throughout rather than float64, avoiding floating-point precision loss when checking minimum/maximum/multipleOf against large or fractional JSON numbers. An optional httploader subpackage (httploader/httploader.go) is imported separately (via a blank import of .../v5/httploader) to add HTTP(S) schema loading, keeping the core package free of a net/http dependency for consumers who only validate local schemas. The cmd/jv CLI is a separate Go module in the same repo, versioned independently from the library.

Code Quality Testing relies heavily on the official JSON-Schema-Test-Suite pulled in as a git submodule (.gitmodules) and driven by schema_test.go, with an explicit skipTests variable documenting which optional suite cases are excluded and why — a notably transparent approach to spec-compliance claims. Additional unit tests cover formats (format_test.go), extensions (extension_test.go), and internal helpers (internal_test.go), and example files (example_test.go, example_extension_test.go) double as executable documentation via Go’s example-test convention. Error handling favors explicit error returns (*SchemaError, *ValidationError, InfiniteLoopError, InvalidJSONTypeError) over panics, aside from a deliberate panic/recover pair in validateValue used to unwind deeply recursive validation on loop detection. CI (.github/workflows/go.yaml) runs go vet and the test suite; a .golangci.yml config indicates linting is part of the standard workflow, though it is not enforced as a blocking CI step in this snapshot.

What Makes It Unique Most Go JSON Schema libraries pick one draft version and validate against it; this one compiles a single document against whichever draft its $schema declares, letting an application load schemas authored at different spec generations (and referencing each other) inside one process without maintaining parallel validators. The fully public, introspectable Schema struct is unusual among validators-as-libraries — it’s designed to be walked by other tools (schema-to-struct generators, documentation generators), not just called via a black-box Validate(v) method. Combined with big.Rat-based numeric comparison and an extension mechanism for custom keywords, the library leans toward being a general-purpose JSON Schema toolkit rather than a narrowly scoped validation function.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search