Stof vs. JSON Schema

TL;DR

  • JSON Schema is great for validation and documentation of static data structures

  • Stof does validation plus transformation, computation, and execution, all in one document

If you need to validate JSON, use JSON Schema. If you need your data to validate itself and perform transformations, use Stof.

JSON Schema is an add-on tool for using JSON only. Although Stof can be used for this as well, given JSON interoperability, it is a separate standard and a stand-alone, portable data format & execution environment.

Comparison

Both let you:

  • Define data structures with types

  • Validate data against constraints

  • Document your data format

  • Work with existing JSON data

Feature
JSON Schema
Sto

Validation

Declarative rules

Executable logic

Transformation

Requires external code

Built-in functions

Computation

Static definitions only

Data can compute itself

Portability

JSON everywhere

Works with JSON, YAML, TOML, etc.

Execution

Schema is separate from runtime

Sandboxed execution included

Ecosystem

Large (most languages)

🟡 Growing (Rust, JS/TS, Python planned)

When to use JSON Schema

Best for:

  • API documentation and validation (OpenAPI, Swagger)

  • Static type checking of JSON documents

  • Projects where separation of schema and logic is preferred

  • Maximum ecosystem compatibility (every language has validators)

Example use case: "I need to validate that API requests match my expected format before processing them."

When to use Stof

Best for:

  • Self-validating configs (validation logic lives with the data)

  • Data transformations that travel with the data

  • Dynamic validation rules that depend on runtime context

  • Sending both data and processing logic over APIs

  • Data pipelines where transformations are part of the document

Example use case: "I need my config file to validate itself AND compute derived values without external code."

Example

JSON Schema

{
  "type": "object",
  "properties": {
    "port": {
      "type": "integer",
      "minimum": 1024,
      "maximum": 65535
    },
    "host": {
      "type": "string",
      "format": "hostname"
    }
  },
  "required": ["port", "host"]
}

Stof

port: 8080
host: "localhost"

fn valid() -> bool {
    self.port >= 1024 && self.port <= 65535 && self.host != ""
}

Embedded in TS/JS

import { StofDoc } from "jsr:@formata/stof";
const doc = await StofDoc.new();

doc.parse(`
port: 8080
host: "localhost"

fn valid() -> bool {
    self.port >= 1024 && self.port <= 65535 && self.host != ""
}
`);

// valid, etc.. (Hint: try parsing data and Stof functions separately.. aha!)
const valid = await doc.call('valid');

Performance Considerations

JSON Schema:

  • ✅ Fast validation (compiled validators)

  • ✅ No runtime overhead beyond validation

  • ❌ Requires external code for transformations

Stof:

  • ✅ Validation + transformation in one pass

  • 🟡 Sandboxed execution has some overhead

  • ✅ No need to serialize/deserialize between steps

Benchmark example (validating + transforming 10k records):

  • JSON Schema + JavaScript: ~50ms validation + ~30ms transformation = 80ms total

  • Stof: ~60ms (validation + transformation together)

Note: Benchmarks vary by use case. Stof's advantage grows when you need multiple transformation steps.

Security Model

JSON Schema:

  • ✅ Pure data, no execution risk

  • ❌ Validation happens in your app's execution context

Stof:

  • ✅ Sandboxed execution (functions can't access filesystem by default)

  • ✅ Resource limits (prevent infinite loops, memory exhaustion)

  • ✅ Explicit permissions for I/O operations

  • 🟡 You're executing code from data (mitigated by sandbox)

Verdict: JSON Schema is "safer" (no execution), but Stof's sandbox makes executable data practical for untrusted sources.

Learn More

Last updated

Was this helpful?