Skip to content

What is Standard Schema?

An introduction to Standard Schema and why FieldTest uses it.

Overview

Standard Schema is a language-agnostic specification for defining data structures and validation rules. It provides a common format that works across different programming languages, frameworks, and tools.

Think of it as a "universal language" for describing what your data should look like.


Why Standard Schema Matters

The Problem

Different validation libraries use different formats:

typescript
// Zod
const zodSchema = z.object({
  title: z.string(),
  count: z.number()
});

// Yup
const yupSchema = yup.object({
  title: yup.string().required(),
  count: yup.number().required()
});

// JSON Schema
const jsonSchema = {
  type: "object",
  properties: {
    title: { type: "string" },
    count: { type: "number" }
  }
};

Each library has its own API and learning curve. Switching between them requires rewriting schemas.

The Solution

Standard Schema provides one format that works everywhere:

typescript
const standardSchema = {
  version: '1',
  name: 'example',
  fields: {
    title: { type: 'string', required: true },
    count: { type: 'number', required: true }
  }
};

This schema can be:

  • ✅ Validated by FieldTest
  • ✅ Understood by humans
  • ✅ Generated by AI tools
  • ✅ Shared across projects
  • ✅ Converted to other formats

Core Concepts

1. Versioned

Schemas include a version number for future compatibility:

typescript
{
  version: '1',  // Currently version 1
  name: 'user-profile',
  fields: { /* ... */ }
}

When Standard Schema evolves, new versions will be introduced while maintaining backwards compatibility.

2. Named

Every schema has a unique name for identification:

typescript
{
  version: '1',
  name: 'blog-post',  // Unique identifier
  fields: { /* ... */ }
}

Names help with:

  • Schema registration and reuse
  • Error reporting
  • Documentation generation
  • Tool integration

3. Field-Based

Schemas define fields with types and constraints:

typescript
{
  version: '1',
  name: 'product',
  fields: {
    sku: { 
      type: 'string', 
      required: true,
      description: 'Unique product identifier'
    },
    price: { 
      type: 'number', 
      required: true 
    },
    tags: { 
      type: 'string', 
      array: true 
    }
  }
}

Each field specifies:

  • Type — Data type (string, number, boolean, date, array, object)
  • Required — Whether the field must be present
  • Array — Whether the field contains multiple values
  • Description — Human-readable explanation
  • Default — Default value if not provided

4. Metadata-Rich

Schemas can include metadata for documentation and tooling:

typescript
{
  version: '1',
  name: 'blog-post',
  fields: { /* ... */ },
  metadata: {
    description: 'Schema for blog post frontmatter',
    author: 'Jane Doe',
    lastUpdated: '2025-01-15',
    tags: ['content', 'markdown']
  }
}

Supported Field Types

Standard Schema supports these primitive types:

TypeDescriptionExample
stringText content"Hello World"
numberNumeric values42, 3.14
booleanTrue/falsetrue, false
dateISO date strings"2025-01-15", "2025-01-15T10:30:00Z"
arrayLists of valuesSet array: true on field
objectNested structuresFor complex nested data

String Type

typescript
fields: {
  title: { 
    type: 'string', 
    required: true,
    description: 'Post title'
  }
}

Number Type

typescript
fields: {
  age: { 
    type: 'number', 
    required: true 
  },
  price: { 
    type: 'number', 
    required: false,
    default: 0
  }
}

Boolean Type

typescript
fields: {
  published: { 
    type: 'boolean', 
    required: true,
    default: false
  }
}

Date Type

typescript
fields: {
  publishedAt: { 
    type: 'date', 
    required: true 
  },
  updatedAt: { 
    type: 'date', 
    required: false 
  }
}

Arrays

Use array: true to indicate a field contains multiple values:

typescript
fields: {
  tags: { 
    type: 'string', 
    array: true,
    description: 'List of tags'
  },
  scores: { 
    type: 'number', 
    array: true 
  }
}

How FieldTest Uses Standard Schema

FieldTest implements Standard Schema for markdown validation:

typescript
import { loadUserSchema, validateWithSchema } from '@watthem/fieldtest';
import type { StandardSchemaV1 } from '@watthem/fieldtest';

// 1. Define schema
const schema: StandardSchemaV1 = {
  version: '1',
  name: 'blog-post',
  fields: {
    title: { type: 'string', required: true },
    published: { type: 'boolean', required: true }
  }
};

// 2. Load schema
const loadedSchema = loadUserSchema(schema);

// 3. Validate content
const markdown = `
---
title: "My Post"
published: true
---
Content here
`;

const result = validateWithSchema(markdown, loadedSchema);

if (result.valid) {
  console.log('✓ Valid!');
}

Benefits for FieldTest Users

  1. Easy to learn — Simple, intuitive schema format
  2. Portable — Schemas work across different tools
  3. Type-safe — Full TypeScript support
  4. AI-friendly — LLMs understand Standard Schema
  5. Future-proof — Versioned for evolution
  6. Interoperable — Works with other Standard Schema tools

Comparison with Other Formats

vs. Zod

Zod (TypeScript-specific):

typescript
import { z } from 'zod';

const schema = z.object({
  title: z.string(),
  count: z.number().min(0).max(100)
});

Standard Schema (universal):

typescript
const schema = {
  version: '1',
  name: 'example',
  fields: {
    title: { type: 'string', required: true },
    count: { type: 'number', required: true }
  }
};

When to use:

  • Zod — Complex runtime validation, TypeScript-only projects
  • Standard Schema — Cross-platform, simple validation, AI integration

vs. JSON Schema

JSON Schema:

json
{
  "type": "object",
  "properties": {
    "title": { "type": "string" },
    "count": { "type": "number" }
  },
  "required": ["title", "count"]
}

Standard Schema:

typescript
{
  version: '1',
  name: 'example',
  fields: {
    title: { type: 'string', required: true },
    count: { type: 'number', required: true }
  }
}

When to use:

  • JSON Schema — Complex validation, extensive ecosystem
  • Standard Schema — Simpler syntax, better for content validation

Design Philosophy

Standard Schema follows these principles:

1. Simplicity First

Schemas should be easy to read and write. No complex nesting or obscure syntax.

typescript
// Good - clear and simple
{
  version: '1',
  name: 'user',
  fields: {
    name: { type: 'string', required: true }
  }
}

// Avoid - unnecessarily complex
{
  version: '1',
  name: 'user',
  fields: {
    name: { 
      type: 'string',
      validators: [{ type: 'required', value: true }],
      transforms: [],
      metadata: { level: 1 }
    }
  }
}

2. Language Agnostic

Schemas are plain JSON/JavaScript objects that work in any language.

3. Human and Machine Readable

Schemas should be understandable by developers, content creators, and AI tools.

4. Versioned for Evolution

The version field allows the specification to evolve without breaking existing schemas.


Real-World Example

Here's a complete Standard Schema for a documentation page:

typescript
import type { StandardSchemaV1 } from '@watthem/fieldtest';

export const docPageSchema: StandardSchemaV1 = {
  version: '1',
  name: 'documentation-page',
  fields: {
    // Required fields
    title: {
      type: 'string',
      required: true,
      description: 'Page title shown in navigation'
    },
    description: {
      type: 'string',
      required: true,
      description: 'Short description for SEO'
    },
    
    // Optional fields
    author: {
      type: 'string',
      required: false,
      description: 'Page author'
    },
    lastUpdated: {
      type: 'date',
      required: false,
      description: 'Last modification date'
    },
    
    // Arrays
    tags: {
      type: 'string',
      array: true,
      description: 'Content tags for search'
    },
    relatedPages: {
      type: 'string',
      array: true,
      description: 'Links to related documentation'
    },
    
    // Booleans with defaults
    draft: {
      type: 'boolean',
      required: false,
      default: false,
      description: 'Whether page is a draft'
    },
    showToc: {
      type: 'boolean',
      required: false,
      default: true,
      description: 'Show table of contents'
    }
  },
  metadata: {
    description: 'Schema for documentation pages',
    version: '1.0.0',
    author: 'Docs Team'
  }
};

Learn More

Released under the MIT License.