Skip to content

woolkingx/schema-driven-development

Repository files navigation

Schema-Driven Development

JSON Schema is an Object DSL. The ecosystem reduced it to a validator config. SDD uses it as a class definition language.

License: MIT PRs Welcome

中文文档 | 日本語

The Problem

A JavaScript object has state and behavior together:

const User = {
  email: "alice@example.com",
  age: 30,
  is_adult() { return this.age >= 18 }
}

JSON serialization stripped the methods for transport. The ecosystem never put them back. Types got scattered across TypeScript interfaces, Rust structs, Python dataclasses — all duplicates of the same thing, all drifting out of sync.

Core Concept

JSON Schema Draft-07 is a DSL — it has a type system, composition, logic (allOf/anyOf/oneOf/not), and control flow (if/then/else). The ecosystem used it only as a validator config. SDD uses the full DSL.

Draft-07 as DSL          →  type system + logic + composition + control flow
What it already covers   →  state definition + method body logic
What SDD adds            →  three namespaces: x-methods, x-tests, x-docs
What you get             →  one JSON document = one complete class definition

Write the class in this DSL. Derive everything else — types, validation, tests, docs.

🚀 Quick Example

Traditional Way (2.5 hours)

TypeScript:

// Define types (30 min)
interface User {
  id: string;
  email: string;
  name: string;
}

// Write validation (30 min)
function validateUser(data: any): data is User {
  if (typeof data.id !== 'string') return false;
  if (typeof data.email !== 'string') return false;
  // ... 50 more lines
}

// Write docs (20 min)
// Write tests (40 min)
// Sync with backend (20 min)
// Business logic (30 min)

Rust:

// Duplicate everything in Rust (1 hour)
struct User { /* ... */ }
fn validate_user() { /* ... */ }

Schema-DD Way

One schema — complete class definition:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "User",
  "type": "object",

  "properties": {
    "email": {"type": "string", "format": "email"},
    "age":   {"type": "integer", "minimum": 0},
    "roles": {"type": "array", "items": {"enum": ["admin", "user", "guest"]}, "minItems": 1}
  },
  "required": ["email", "roles"],

  "x-methods": {
    "is_adult": {"properties": {"age": {"minimum": 18}}},
    "is_admin": {"properties": {"roles": {"contains": {"const": "admin"}}}}
  },

  "x-tests": {
    "is_adult": ["min_boundary", "below_min", "null", "valid_normal"]
  },

  "x-docs": {
    "intent": "Core user entity for authentication and authorization.",
    "category": "auth"
  }
}

Use directly as an object (Python):

from schema2object import ObjectTree

user = ObjectTree({"email": "alice@example.com", "age": 30, "roles": ["admin"]}, schema=schema)
user.email        # "alice@example.com"
user.one_of()     # dispatch by oneOf branch
user.project()    # keep only schema-defined fields

Or in Rust:

let user = SchemaValue::new(data, schema);
user["email"]          // "alice@example.com"
user.one_of()?         // XOR dispatch
user.validate()?       // constraint enforcement

Everything else is derived: types, validation, tests, docs — from one schema.

🌟 Real-World Success Stories

Case 1: Claude TUI RS (Streaming Events)

Challenge: Terminal UI with 14 streaming event types

Solution: JSON-as-Object Pattern + DynamicEvent API

Results:

  • 40x faster development (3 min vs 2 hours per event type)
  • 100% doc accuracy (schema auto-generates docs)
  • Zero type errors (runtime validation + dynamic property access)
  • 9 passing tests (schema = tests)

Details →

Case 2: UI Component Library ⭐ Killer App

Challenge: Cross-platform UI library, 50+ components, perfect frontend/backend alignment

Solution: Schema Registry + Component Library Pattern

Results:

  • 4-6x faster development (30 min vs 2-3 hours per component)
  • 88% maintenance cost reduction (5h vs 40h per month)
  • 100% design system consistency (enforced, can't violate)
  • Perfect cross-platform sync (Web/Mobile/Backend same schema)

Killer Features:

  • One Schema = Props + Validation + Docs + Storybook
  • Add component: Write 10 lines JSON → auto-generate everything
  • Design system enforcement: $ref: colors.schema.json → impossible to violate
  • Frontend/backend alignment: Same schema, all platforms

Details →

Case 3: MCP Server Template

Challenge: Build reusable MCP servers with zero hardcoded values

Solution: config.json as root schema, $ref chain drives all runtime behavior

Results:

  • Complete MCP 2025-03-26 spec coverage — all 15 protocol methods routed and handled
  • Three transports: stdio, Streamable HTTP, CLI
  • Official mcp-schema.json (83 definitions) — no hand-written simplification
  • Three output formats: json, md, file (write to disk)
  • 98 tests across 9 suites (schema/runtime/system/output/unit/edge)
  • Security hardened: path traversal blocked, ReDoS capped, CORS schema-driven

Schema drives everything: server name, log level, port, error codes, protocol version, capabilities, CORS headers, session management, shutdown signals, output format, file naming patterns.

Details →

Templates

Production-ready starter templates built on SDD principles:

Template Description Tests
mcp-server Complete MCP server — 3 transports, 15 spec methods, 3 output formats 98

Copy a template, edit project/ directory, run. Schema handles the rest.

Documentation Structure

schema-driven-development/
├── README.md                              # You are here
├── SKILL.md                               # Complete development workflow
│
├── methodology/                           # Philosophy and specs
│   ├── sdd-philosophy.md                 # JSON Schema as Object DSL
│   ├── x-extensions.md                   # x-methods / x-tests / x-docs spec
│   └── type-system-revolution.md         # Type system analysis
│
├── references/                            # Language implementations
│   ├── quick-start.md                    # Start here
│   ├── python/
│   │   └── schema2object.md              # Python ObjectTree API
│   ├── rust/
│   │   ├── schema-value.md               # Rust SchemaValue API
│   │   └── jsonschema-runtime.md         # External crate usage
│   └── typescript/
│       └── ajv-validation.md             # Frontend validation
│
├── templates/                             # Production-ready starter templates
│   └── mcp-server/                       # MCP server (98 tests, complete MCP 2025-03-26 spec)
│
├── examples/                              # Runnable examples
│   ├── schema-registry.rs                # Rust Registry
│   └── ci-cd-workflow.yml                # GitHub Actions
│
└── case-studies/                          # Real projects
    ├── claude-tui-rs/                    # Streaming events
    └── ui-component-library/             # Component library

Learning Path

Start

  1. Quick Start — write a schema, use it as an object (Python + Rust)
  2. SDD Philosophy — JSON Schema as Object DSL
  3. x- Extensions — x-methods / x-tests / x-docs spec

Go Deeper

  1. SKILL.md — complete development workflow
  2. schema2object — Python API reference
  3. schema-value — Rust API reference
  4. CI/CD — automate derivation

Build Something

  1. MCP Server Template — copy, edit schema, run

Real Projects

  1. Claude TUI RS — 14 streaming event types
  2. UI Component Library — 50+ components
  3. mcp-arango-mind — ArangoDB MCP (250+ operations)
  4. mcp-personal-rss — RSS feed reader (17 actions)

Contributing

  • Report bugs
  • Share real-world case studies
  • Contribute language implementations (Go, Java, TypeScript, Swift)

See CONTRIBUTING.md

License

MIT License

About

The Type System Revolution: Stop wasting 70% of your time on types, focus on business logic | Latest at Codeberg: https://codeberg.org/woolkingx/schema-driven-development

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors