Overview
November 5, 2025 ยท View on GitHub
simple-json-schema is a tool for specifying JSON schemas, and validating that
JSON documents conform to the schema. It is similar to other tools,
such as JSON Schema, but it aims for a more readable schema specification
language, based on TypeScript types.
Usage
The most common way to use the tool are as follows:
# Check if `my-schema.ts` is a valid schema specification
simple-json-schema my-schema.ts
# Check if `my-doc.json` conforms to the schema described in `my-schema.ts`
simple-json-schema my-schema.ts --validate=my-doc.json
By default, the tool will validate against the first definition the schema
file. To specify a different definition, you may use the --entry flag:
simple-json-schema my-schema.ts --validate=my-doc.json --entry=SomeDef
Writing Schemas
A schema file is very similar to a TypeScript file containing a collection of type synonyms. The following grammar specifies the format of schemas, describes the intended semantics, and points out deviations from TypeScript.
SCHEMA := IMPORT* TYPE_DEF*
// The schema may contain comments as in TypeScript.
// These are generally ignored, except line comments starting with
// 3 slashes, which are doc-comments and may appear only before
// definitions or field constraints as described below.
IMPORT :=
import * as IDENT from STRING
// Use all definitions from file STRING, with names qualified by IDENT.
// For example, if "Other.ts" defines `x`, then
// `import * as O from "Other.ts"` will introduce `O.x` in scope.
// NOTE: This is different from TypeScript in that it does not refer
// to the default export.
| import { IDENT (,IDENT)* } from STRING
// Use only the listed definitions from file STRING, with unqualified names.
// For example, `import { a, b } from "Other.ts"` will introduce
// definitions `a` and `b` defined in "Other.ts" to the current scope.
TYPE_DEF :=
type IDENT = TYPE
// Define a named type.
// A definition may be preceded by some line doc-comments
// (i.e., lines starting with `///`).
// Definitions may be recursive, but only under a value constructor.
// For example, `type X = [X] | boolean` is OK, but `type X = X | boolean`
// is not.
// NOTE: A deviation form TypeScript is that all definitions are considered
// to be exported, so there is no need to write an explicit `export`.
TYPE :=
IDENT | IDENT.IDENT
// Match the values accepted by this named type.
| LITERAL
// Match a specific JSON value.
| TYPE "|" TYPE
// Match a value accepted by either type.
// For example `"A" | "B"` matches either the JSON value "A" or "B".
| boolean
// Match any boolean JSON value.
// Equivalent to `true | false`.
| number
// Match any numeric JSON value.
| string
// Match any string JSON value.
| any
// Match any JSON value.
| {} | { FIELD (,FIELD)* }
// Match a JSON object, whose fields match the given FIELDs.
// The order of the fields is not important, and fields cannot
// be repeated.
| TYPE[]
// Matches a JSON array, whose values match TYPE.
// For example, `number[]` matches arrays with number elements.
| "(" TYPE ")"
// Parens may be used for grouping, as usual.
// For example `("a" | "b")[]` matches arrays
// whose elements are `"a"` or `"b"`
| [] | [ TYPE (,TYPE)* ]
// Matches JSON arrays of a fixed length, with elements matching types
// in the corresponding positions.
// For example `[boolean,string]` matches 2 element arrays, where the
// first element should be a boolean, and the second one should be a string.
| TYPE?
// Equivalent to `TYPE | null`.
// NOTE: this is not a valid TypeScript type.
LITERAL :=
null
// Matches the value `null`
| false
// Matches the value `false`
| true
Matches the value `true`
| STRING
// Matches this specific string literal in JSON format
| NUMBER
// Matches this specific numeric literal in JSON format
FIELD :=
FIELD_NAME : TYPE
// The object must have a field with the given name and matching TYPE
// A field may be preceded by some line doc-comments
// (i.e., lines starting with `///`).
| FIELD_NAME? : TYPE
// The object is not required to have this field, but if it does,
// then it should match TYPE
// A field may be preceded by some line doc-comments
// (i.e., lines starting with `///`).
| ...
// Matches any fields that are not matched by another FIELD in the
// object specification.
// For example `{ x: boolean, ... }` matches objects that must have
// a boolean field name `x` and may have any other fields.
// In contrast, `{ x: boolean }` matches objects that have exactly one
// boolean field named `x`.
// NOTE: This is not a valid TypeScript type.
FIELD_NAME := IDENT | STRING
// Quotes in field name are optional if the field is just an identifier.