JSON schema for the win

How to get IntelliSense help for your JSON files in modern IDEs.

I have noticed a curious thing while editing tsconfig.json file the other day. I was using VSCode and there was an IntelliSense popup as I started entering a property name in a JSON object.

IntelliSense popup in tsconfig.json

Then I have noticed the same happening while editing package.json. Here is me hovering over the property main. Seems accurate.

IntelliSense popup in package.json

The editor was quite helpful - not only it is displaying suggestions, it also highlights as errors places where I am trying to enter invalid values.

Entering a number for main

The editor "knows" that main property should have a string value, and not a number.

So I have decided to investigate how the editor knows what properties are supposed to be in the tsconfig.json or package.json? Searching around I found VSCode Json editing docs. Turns out the secret to the IntelliSense "superpowers" is that the editor finds schema for the JSON file by name. For tsconfig.json there is a public schema at json.schemastore.org/tsconfig. It describes every property, here is a small part

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"title": "JSON schema for the TypeScript compiler's configuration file",
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"filesDefinition": {
"properties": {
"files": {
"description": "If no 'files' or 'include' property ...",
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
...
}

There are a lot of schemas for widely used JSON files on schemastore.org/json/ and you can add your own by making a pull request.

Cypress.json schema

I have been working a lot on Cypress test runner - after all, it is my job. All Cypress options can be configured inside the cypress.json file in the user project. Guess what - there are LOT of options. I constantly had to look up configuration names and allowed values myself!

A JSON schema would be super helpful. So I wrote one, by mostly copying the property descriptions from the documentation and pasting them into the JSON file. You can find the result here.

I have opened a pull request #384 to add a schema for cypress.json file. This pull request is a little unusual. Instead of uploading a static JSON file to the schemastore, I only added a record to their catalog to point at JSON schema file stored in our https://github.com/cypress-io/cypress repo.

1
2
3
4
5
6
{
"name": "cypress.json",
"description": "Cypress.io test runner configuration file",
"fileMatch": [ "cypress.json" ],
"url": "https://raw.githubusercontent.com/cypress-io/cypress/develop/cli/schema/cypress.schema.json"
}

While waiting for the Schemastore pull request to be accepted, I wanted to start using the schema file. Luckily, VSCode allows me to configure my own settings right away.

Open "Preferences" - "Settings" - "User Settings". Then add a new section to the object.

1
2
3
4
5
6
7
8
9
10
{
"json.schemas": [
{
"fileMatch": [
"/cypress.json"
],
"url": "https://raw.githubusercontent.com/cypress-io/cypress/develop/cli/schema/cypress.schema.json"
}
]
}

Boom! Open any cypress.json file and start enjoying life in the fast lane.

If you do not have public JSON schema that works for everyone (for example if you have multiple versions of config files), you can distribute the JSON schema file with your JSON file and point at it using a property in the JSON file itself. For example, in the cypress.json you could do

1
2
3
4
{
"baseUrl": "http://localhost:8000",
"$schema": "../node_modules/cypress/schema/cypress.schema.json"
}

VSCode and other editors are smart enough to find and apply schema file from the relative path or from URL specified in the $schema property.

Happy coding!