README
¶
SchemaKit
JSON Schema toolkit for Go developers.
Overview
schemakit is a toolkit for working with JSON Schema in Go projects. It provides:
- Linting - Validate schemas for compatibility with statically-typed languages
- Generation - Generate JSON Schema from Go struct types
- Documentation - Generate Markdown specification docs from Go types
Installation
Homebrew
brew install grokify/tap/schemakit
Go Install
go install github.com/grokify/schemakit/cmd/schemakit@latest
Commands
| Command | Description |
|---|---|
schemakit lint |
Check schemas for static type compatibility |
schemakit generate |
Generate JSON Schema from Go struct types |
schemakit doc |
Generate Markdown documentation from Go types |
schemakit version |
Print version information |
Usage
Generate Schema from Go Types
Generate a JSON Schema from Go struct types:
schemakit generate github.com/myorg/myproject/types Config
schemakit generate -o schema.json github.com/myorg/myproject/types Config
This creates a temporary Go program that uses invopop/jsonschema to reflect on your type and generate the schema. The target package can be local (in GOPATH/src) or remote.
Generate Documentation from Go Types
Generate Markdown specification documentation from Go struct types:
# Generate to stdout
schemakit doc github.com/grokify/threat-model-spec/ir ThreatModel
# Generate with title and version, save to file
schemakit doc -t "Threat Model Specification" -v v0.4.0 \
github.com/grokify/threat-model-spec/ir ThreatModel -o spec.md
# Prepend custom header (overview, examples, references)
schemakit doc --prepend header.md \
github.com/grokify/threat-model-spec/ir ThreatModel -o spec.md
The doc command extracts:
- Package doc comments as overview
- Type descriptions from doc comments
- Field names and JSON tags
- Required vs optional fields (based on
omitempty) - Enum types (
type X string) and their const values - Enum value descriptions from const doc comments
- Generates Type Reference and Enum Reference sections
Lint Schema
Check a JSON Schema for patterns that cause problems in code generation:
schemakit lint schema.json
Profiles
Use --profile to select a linting profile:
schemakit lint schema.json # default profile
schemakit lint schema.json --profile scale # strict scale profile
| Profile | Description |
|---|---|
default |
Standard checks for discriminators, union size, nesting |
scale |
Strict mode that disallows composition keywords for clean static types |
Output Formats
schemakit lint --output text schema.json # Human-readable (default)
schemakit lint --output json schema.json # Machine-readable JSON
schemakit lint --output github schema.json # GitHub Actions annotations
Exit Codes
| Code | Meaning |
|---|---|
| 0 | No issues found |
| 1 | Errors found (schema has problems) |
| 2 | Warnings found but no errors |
Lint Checks
Default Profile
Errors
| Code | Description |
|---|---|
union-no-discriminator |
Union (anyOf/oneOf) has no discriminator field |
inconsistent-discriminator |
Variants use different discriminator field names |
missing-const |
Union variant lacks const value for discriminator |
duplicate-const-value |
Multiple variants have the same discriminator value |
invalid-property-case |
Property name does not follow the configured case convention |
Warnings
| Code | Description |
|---|---|
large-union |
Union has more than 10 variants |
nested-union |
Union nested more than 2 levels deep |
additional-properties |
Union variant has additionalProperties: true |
Scale Profile
The scale profile includes all default checks plus these additional errors:
| Code | Description |
|---|---|
composition-disallowed |
Disallow anyOf, oneOf, allOf |
additional-properties-disallowed |
Disallow additionalProperties: true |
missing-type |
Require explicit type field |
mixed-type-disallowed |
Disallow type arrays like ["string", "number"] |
Example
Given this schema with a union that lacks a discriminator:
{
"$defs": {
"Response": {
"anyOf": [
{"type": "object", "properties": {"data": {"type": "string"}}},
{"type": "object", "properties": {"error": {"type": "string"}}}
]
}
}
}
Running schemakit lint will report:
[error] $/$defs/Response/anyOf: anyOf union has no discriminator field
suggestion: Add a const property (e.g., 'type' or 'kind') to each variant with a unique value
Summary: 1 error(s), 0 warning(s)
Fix by adding a discriminator:
{
"$defs": {
"Response": {
"anyOf": [
{
"type": "object",
"properties": {
"type": {"const": "success"},
"data": {"type": "string"}
}
},
{
"type": "object",
"properties": {
"type": {"const": "error"},
"error": {"type": "string"}
}
}
]
}
}
}
Go-First Workflow
schemakit supports a Go-first approach where Go structs are the source of truth:
Go Structs (with doc comments)
│
├──► schemakit generate ──► JSON Schema
│
└──► schemakit doc ──► Markdown Specification
This ensures your JSON Schema and documentation are always in sync with your Go types.
Roadmap
See TASKS.md for planned features including:
- Code generation for Go, Rust, TypeScript
- Full
$refresolution - OpenAPI 3.1 support
Documentation
Full documentation is available at grokify.github.io/schemakit.
Key guides:
- Spec Documentation Guide - Creating human-audience specs with auto-generation
- Go-First Workflow - Complete workflow guide
- Lint Checks Reference - All lint check codes
References
- PRD.md - Product requirements
- TRD.md - Technical requirements
- JSON Schema Draft 2020-12
License
MIT License - see LICENSE for details.