Publish a JSON Schema

François Best • 12 October 2023 • 3 min read

If you’ve worked with files like package.json or tsconfig.json in TypeScript projects in VSCode, you know the benfits of having good autocompletion in your editor.

This is powered by JSON Schemas, which are JSON files that describe the shape of other JSON files.

Using an existing schema to document a JSON file is done with the $schema property, pointing to a URL to the schema file:

tsconfig.json
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "compilerOptions": {
    // ...
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules"]
}

There is a project called SchemaStore that lists a bunch of schemas for popular JSON files, but there are many more that are not listed there, especially those handcrafted for specific projects, or for bleeding edge tools.

You can publish your own JSON Schema to SchemaStore via their GitHub repository, but you can also publish it anywhere you like, and link from there.

One example is publishing your schema on GitHub, and using the raw URL to refer to it:

sceau.json
{
  "$schema": "https://raw.githubusercontent.com/47ng/sceau/main/src/schemas/v1.schema.json"
  // ...
}

Validation

VSCode will automatically validate your JSON file against the schema, but you can perform verification manually using the ajv package.

It’s unfortunately not a one-liner command line trick, as AJV requires the schema file to exist on disk first, and doesn’t support reading from stdin.

You can use the following Node.js script to perform this task:

validate.mjs
import Ajv from 'ajv'
import addFormats from 'ajv-formats'
import fs from 'node:fs/promises'
 
const fileContents = await fs.readFile(process.argv[2], 'utf-8')
const jsonToValidate = JSON.parse(fileContents)
const schema = await fetch(jsonToValidate.$schema).then(res => res.json())
const ajv = new Ajv()
addFormats(ajv)
const isValid = ajv.validate(schema, jsonToValidate)
if (!isValid) {
  console.error(validator.errors)
  process.exit(1)
}
console.info(`File conforms to schema ${jsonToValidate.$schema}`)
node validate.mjs file-to-test.json

Versioning

Another nice property of using a URL is that you can — and shouldversion your schema files, and the $schema property will act as a versioning indicator of the JSON file that contains it.

No longer need for the following:

{
  "version": 2 // What was that one about again?
  // ...
}

Generating JSON Schemas

Now if have a bunch of JSON files, and you want to generate a schema for them, you could do it manually, but it’s a bit tedious.

You can ask an LLM to do that for you, they are surprisingly good at manipulating structured data, but you might need to check for hallucinations and tweak the output a bit.

Generate a JSON schema for an arbitrary JSON file provided as standard input.

The schema should include descriptions for each field, and disallow additional properties.

Possible GPT-n prompt

Go ahead and publish a JSON Schema for your data!


François Best

Freelance developer & founder