goldenthread

package module
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 26, 2026 License: Apache-2.0, MIT Imports: 0 Imported by: 0

README

goldenthread

Schema compiler: Go structs → TypeScript/Zod. Keep backend/frontend validation in sync automatically.

Go Reference Go Version CI Lint

License Sponsor

goldenthread is a build-time schema compiler that generates production-ready Zod validation from Go structs. Write validation rules once in Go tags, get type-safe TypeScript schemas automatically. Built-in drift detection catches schema mismatches in CI. No manual synchronization. No runtime overhead.

Overview

Maintaining validation across Go backends and TypeScript frontends means keeping multiple representations synchronized. goldenthread generates Zod schemas directly from Go struct tags:

// Go: Define once with validation tags
type User struct {
  Username string `json:"username" gt:"required,len:3..20"`
  Email    string `json:"email" gt:"email"`
  Age      int    `json:"age" gt:"min:13,max:130"`
}
# Generate Zod schemas
goldenthread generate ./models
// TypeScript: Use generated schemas
import { UserSchema, User } from './gen/user'

// Runtime validation
const result = UserSchema.safeParse(data)

// Type inference
const user: User = {
  username: 'alice',
  email: 'alice@example.com',
  age: 25
}

Changes to Go structs regenerate TypeScript schemas automatically. The compiler ensures they stay synchronized.

Features

goldenthread generates production-ready Zod schemas with complete type safety.

What You Get
  • Full Go type support: Primitives, arrays, maps, enums, nested objects, pointers
  • Comprehensive validation: Length bounds, numeric ranges, regex patterns, format validators (email, UUID, URL, IPv4/IPv6, datetime)
  • Enum generation: z.enum(['pending', 'completed']) from Go string fields
  • Map support: z.record(z.string(), T) for Go maps
  • Array validation: Min/max length constraints
  • Nested objects: Type-safe references to other schemas
  • Embedded struct flattening: Anonymous fields promoted automatically
  • Collision detection: Duplicate JSON keys caught at compile time (not runtime)
  • Drift detection: goldenthread check fails CI if schemas out of sync
  • Zero runtime overhead: Pure code generation, no reflection, no magic
Validation Rules
type Product struct {
  // String validation
  Name  string `gt:"required,len:1..100"`
  SKU   string `gt:"pattern:^[A-Z0-9]{8}$"`
  
  // Numeric validation  
  Price float64 `gt:"required,min:0,max:999999.99"`
  Stock int     `gt:"min:0"`
  
  // Format validation
  Email  string `gt:"email"`
  WebURL string `gt:"url"`
  ID     string `gt:"uuid,required"`
  
  // Enum validation
  Status string `gt:"enum:draft,published,archived"`
  
  // Optional fields (pointer or omitempty)
  Notes *string `gt:"len:0..500"`
  Tags  []string `json:"tags,omitempty"`
  
  // Map support
  Metadata map[string]string `gt:"optional"`
}

See docs/TAG_SPEC.md for complete tag syntax.

Installation

go install github.com/blackwell-systems/goldenthread/cmd/goldenthread@latest

Quick Start

1. Define Your Models
// models/user.go
package models

// User represents a system user with validated fields.
type User struct {
  // ID is the unique identifier
  ID string `json:"id" gt:"uuid,required"`
  
  // Username must be 3-20 characters
  Username string `json:"username" gt:"required,len:3..20"`
  
  // Email must be valid format
  Email string `json:"email" gt:"email"`
  
  // Age must be between 13 and 130
  Age int `json:"age" gt:"min:13,max:130"`
  
  // Bio is optional with max length
  Bio *string `json:"bio" gt:"len:0..500"`
}
2. Generate Schemas
# Generate from current directory
goldenthread generate ./models

# Generate recursively
goldenthread generate ./models --recursive

# Specify output directory
goldenthread generate ./models --out ./frontend/src/schemas

Output:

gen/
  user.ts                    # Generated Zod schema
  .goldenthread.json         # Metadata for drift detection
3. Use in TypeScript
import { UserSchema, User } from './gen/user'

// Parse and validate API response
const response = await fetch('/api/users/123')
const data = await response.json()
const result = UserSchema.safeParse(data)

if (!result.success) {
  console.error('Validation failed:', result.error)
  return
}

// Type-safe access
const user: User = result.data
console.log(user.username) // Type: string
console.log(user.bio)      // Type: string | undefined
4. Verify Schemas Stay in Sync
# Check if generated schemas match source
goldenthread check ./models

# Returns exit code 1 if out of sync (CI-friendly)

Add to CI:

- name: Check schema drift
  run: goldenthread check ./models

Architecture

goldenthread is a schema compiler with three stages:

Go Source → Parser → Intermediate Representation → Emitter → Generated Code
            (AST)         (Language-agnostic)        (Zod)    (TypeScript)
Pipeline Components

1. Parser (internal/parser)

Uses go/packages and go/types for proper type resolution. Extracts struct definitions with gt: tags, validates tag syntax and conflicts, handles embedded structs and cross-package references.

2. Intermediate Representation (internal/schema)

Language-agnostic schema format that separates parsing from code generation. Enables future emitters (OpenAPI, JSON Schema, etc.) without modifying the parser.

3. Normalization (internal/normalize)

Flattens embedded struct fields, detects Go field name collisions, validates JSON name collisions, ensures schema correctness before emission.

4. Emitter (internal/emitter/zod)

Generates TypeScript with Zod schemas. Preserves Go documentation as JSDoc, emits type-safe z.infer<> types, produces deterministic output for stable diffs.

5. Hash/Drift Detection (internal/hash)

SHA-256 hashing of schema content with metadata tracking (.goldenthread.json). Detects when source and generated code diverge.

Supported Types

Go Type Zod Output Notes
string z.string() With validation rules
int, int64, float64, etc. z.number() All numeric types
bool z.boolean() Boolean values
[]T z.array(T) Arrays/slices
map[string]T z.record(z.string(), T) String-keyed maps
time.Time z.string().datetime() ISO 8601 datetime
*T T.optional() Pointers become optional
Named struct TypeSchema References to other schemas
Embedded struct Fields flattened Anonymous fields promoted

See docs/FEATURES.md for complete type coverage.

Validation Tags

Presence
  • required - Field must be present (default for non-pointers)
  • optional - Field can be omitted
String Rules
  • len:M..N - Length between M and N characters
  • min:N - Minimum length (shorthand for len:N..)
  • max:N - Maximum length (shorthand for len:..N)
  • pattern:REGEX - Must match regular expression
Numeric Rules
  • min:N - Minimum value
  • max:N - Maximum value
Format Validators
  • email - Valid email address
  • uuid - Valid UUID string
  • url - Valid URL
  • date - ISO 8601 date (YYYY-MM-DD)
  • datetime - ISO 8601 datetime
  • ipv4 - IPv4 address
  • ipv6 - IPv6 address
Enums
  • enum:value1,value2,value3 - One of specified values
Array Rules
  • min:N - Minimum array length
  • max:N - Maximum array length

See docs/TAG_SPEC.md for detailed specification.

Examples

Nested Objects
type Address struct {
  Street  string `json:"street" gt:"required"`
  City    string `json:"city" gt:"required"`
  ZipCode string `json:"zip_code" gt:"pattern:^[0-9]{5}$"`
}

type User struct {
  Name    string  `json:"name" gt:"required"`
  Address Address `json:"address" gt:"required"`
}

Generates nested Zod schema:

const AddressSchema = z.object({
  street: z.string(),
  city: z.string(),
  zip_code: z.string().regex(/^[0-9]{5}$/)
})

const UserSchema = z.object({
  name: z.string(),
  address: AddressSchema
})
Embedded Structs
type Timestamps struct {
  CreatedAt string `json:"created_at" gt:"datetime,required"`
  UpdatedAt string `json:"updated_at" gt:"datetime,required"`
}

type Article struct {
  Timestamps  // Fields automatically flattened
  
  Title   string `json:"title" gt:"required,len:1..200"`
  Content string `json:"content" gt:"required"`
}

Generates flattened schema:

const ArticleSchema = z.object({
  created_at: z.string().datetime(),
  updated_at: z.string().datetime(),
  title: z.string().min(1).max(200),
  content: z.string()
})
Enums
type Task struct {
  Title    string `json:"title" gt:"required"`
  Status   string `json:"status" gt:"enum:pending,in_progress,completed,cancelled"`
  Priority string `json:"priority" gt:"enum:low,medium,high"`
}

Generates enum schemas:

const TaskSchema = z.object({
  title: z.string(),
  status: z.enum(['pending', 'in_progress', 'completed', 'cancelled']),
  priority: z.enum(['low', 'medium', 'high'])
})
Maps
type Config struct {
  Name     string            `json:"name" gt:"required"`
  Settings map[string]string `json:"settings" gt:"required"`
  Metadata map[string]any    `json:"metadata" gt:"optional"`
}

Generates record schemas:

const ConfigSchema = z.object({
  name: z.string(),
  settings: z.record(z.string(), z.string()),
  metadata: z.record(z.string(), z.any()).optional()
})

CLI Commands

generate

Generate Zod schemas from Go source:

goldenthread generate [flags] <directory>

Flags:
  --out <dir>       Output directory (default: ./gen)
  --recursive       Process subdirectories recursively
  --target <name>   Target format (default: zod)
check

Verify generated schemas match source:

goldenthread check [flags] <directory>

Flags:
  --metadata <file>  Metadata file to check against
  --recursive        Process subdirectories recursively

Exit codes:

  • 0 - Schemas in sync
  • 1 - Schemas out of sync or error

Current Limitations

goldenthread v0.1 focuses on the core use case: struct validation for APIs and forms. Click to see what's not yet supported.
Type System
  • Go union types (interfaces with type assertions)
  • Discriminated unions
  • Fixed-length arrays ([3]int)
  • Literal constant values
  • Recursive/self-referential types
Validation
  • Custom validation functions
  • Cross-field validation (password confirmation, etc.)
  • Unique items in arrays
  • Conditional validation
Emitters
  • OpenAPI/Swagger generation
  • JSON Schema generation
  • TypeScript types (separate from Zod)
  • Other validation libraries
Tag Features
  • Tag inheritance/composition
  • Conditional rules
  • Multiple validation sets per struct

These limitations are intentional for v0.1. The tool does one thing well: generate type-safe Zod schemas from Go structs (including primitives, enums, arrays, maps, and nested objects). Future versions may expand scope based on real-world usage.

Comparison with Alternatives

Tool Go → TS Validation Approach Use Case
validator.v10 No Yes Runtime tags Go-only validation
swaggo/swag No No Comments OpenAPI from Go
oapi-codegen Yes Yes OpenAPI → Go Contract-first APIs
protobuf Yes Limited .proto files Cross-language RPC
goldenthread Yes Yes Go → Zod Go-first validation

goldenthread is optimized for teams that:

  • Write backend in Go
  • Write frontend in TypeScript
  • Want Go structs as the source of truth
  • Need runtime validation in both languages
  • Prefer type safety over flexibility

Documentation

Development

Project Structure
goldenthread/
├── cmd/goldenthread/      # CLI tool
├── internal/
│   ├── parser/            # Go AST parsing with go/packages
│   ├── schema/            # Intermediate representation
│   ├── normalize/         # Schema validation and flattening
│   ├── emitter/zod/       # Zod schema generation
│   ├── hash/              # Drift detection
│   └── load/              # Package loading wrapper
├── examples/              # Test cases
└── docs/                  # Documentation

Building
# Build CLI tool
go build ./cmd/goldenthread

# Run tests
go test ./...

# Run with coverage
go test ./... -cover
Contributing

Contributions welcome! Areas of interest:

  1. Additional emitters (OpenAPI, JSON Schema)
  2. More validation rules
  3. Test coverage improvements
  4. Documentation and examples

Philosophy

goldenthread follows these principles:

  1. Go structs are canonical - Not config files, not DSLs, not annotations
  2. Build-time generation - Not runtime reflection or proxies
  3. Type safety everywhere - Catch errors at compile time
  4. Simple over clever - Predictable behavior beats flexibility
  5. Fail fast - Unknown tokens error immediately

The name "goldenthread" comes from traditional weaving: the single continuous strand that holds fabric together. In software, it's the thread of type safety that should run unbroken from domain models through APIs to frontends.

License

Dual-licensed under your choice of:

Most users prefer MIT for simplicity. Apache 2.0 provides additional patent protections.

Trademarks

Blackwell Systems™ and the Blackwell Systems logo are trademarks of Dayna Blackwell. You may use the name "Blackwell Systems" to refer to this project, but you may not use the name or logo in a way that suggests endorsement or official affiliation without prior written permission. See BRAND.md for usage guidelines.

Documentation

Overview

Package goldenthread is a schema compiler that generates TypeScript/Zod validation from Go structs.

Overview

goldenthread generates type-safe validation schemas from Go struct definitions. Define your domain models once in Go with validation tags, and compile them into Zod schemas for TypeScript—automatically.

Quick Start

Define a Go struct with validation tags:

type User struct {
    Username string `json:"username" gt:"required,len:3..20"`
    Email    string `json:"email" gt:"email"`
    Age      int    `json:"age" gt:"min:13,max:130"`
}

Generate Zod schemas:

$ goldenthread generate ./models

Use the generated TypeScript:

import { UserSchema, User } from './gen/user'

const result = UserSchema.safeParse(data)
if (!result.success) {
    console.error('Validation failed:', result.error)
}

Installation

go install github.com/blackwell-systems/goldenthread/cmd/goldenthread@latest

Commands

  • generate: Generate Zod schemas from Go source
  • check: Verify generated schemas are in sync (CI-ready)
  • version: Display version information

Validation Tags

goldenthread supports comprehensive validation rules in the gt: struct tag:

String validation:

Name string `gt:"required,len:1..100"`
SKU  string `gt:"pattern:^[A-Z0-9]+$"`

Numeric validation:

Age   int     `gt:"min:0,max:150"`
Price float64 `gt:"min:0,max:999999.99"`

Format validation:

Email string `gt:"email"`
ID    string `gt:"uuid,required"`
URL   string `gt:"url"`

Enums:

Status string `gt:"enum:draft,published,archived"`

Arrays and maps:

Tags     []string          `gt:"min:1,max:10"`
Metadata map[string]string `gt:"optional"`

Type System

Supported Go types:

  • Primitives: string, int, int64, float64, bool
  • Time: time.Time (mapped to z.string().datetime())
  • Collections: []T, map[string]T
  • Nested structs with references
  • Embedded structs (automatically flattened)
  • Pointer types (become optional: *string → z.string().optional())

CI Integration

Verify schemas stay in sync with source:

goldenthread check ./models

Returns exit code 1 if schemas are out of sync, perfect for CI pipelines.

Architecture

goldenthread uses a five-stage compilation pipeline:

Go source → Parse → Normalize → Hash → Emit → TypeScript
            (AST)    (IR)      (drift) (Zod)   (generated)

The intermediate representation (IR) is language-agnostic, enabling future emitters for OpenAPI, JSON Schema, or other validation frameworks.

Quality Assurance

goldenthread includes comprehensive testing:

  • 53.4% test coverage across all packages
  • 12 fuzz targets running continuously (every 30 minutes)
  • 2 bugs found and fixed by fuzzing before v0.1.0 release
  • CI/CD with automated testing and linting

License

Dual-licensed under Apache-2.0 OR MIT - your choice.

Directories

Path Synopsis
cmd
goldenthread command
goldenthread is a CLI tool for generating TypeScript/Zod validation schemas from Go structs.
goldenthread is a CLI tool for generating TypeScript/Zod validation schemas from Go structs.
examples
ecommerce
Package ecommerce demonstrates a complete e-commerce API schema with: - Nested objects (Address, Payment) - Arrays with validation (OrderItems, Tags) - Enums (OrderStatus, PaymentMethod) - Maps (Metadata) - Optional fields (pointers) - Embedded structs (Timestamps) - Multiple validation rules
Package ecommerce demonstrates a complete e-commerce API schema with: - Nested objects (Address, Payment) - Arrays with validation (OrderItems, Tags) - Enums (OrderStatus, PaymentMethod) - Maps (Metadata) - Optional fields (pointers) - Embedded structs (Timestamps) - Multiple validation rules
internal
emitter/zod
Package zod generates Zod validation schemas from schema IR.
Package zod generates Zod validation schemas from schema IR.
hash
Package hash computes deterministic hashes of schemas for drift detection.
Package hash computes deterministic hashes of schemas for drift detection.
load
Package load uses go/packages to load Go packages with proper type information.
Package load uses go/packages to load Go packages with proper type information.
normalize
Package normalize handles schema normalization including embedded struct flattening.
Package normalize handles schema normalization including embedded struct flattening.
parser
Package parser extracts schema definitions from Go source code using AST analysis.
Package parser extracts schema definitions from Go source code using AST analysis.
schema
Package schema defines the intermediate representation (IR) for domain schemas.
Package schema defines the intermediate representation (IR) for domain schemas.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL