JSON Schema

While TOML itself may introduce schema specifications in the future, Tombi, like Taplo, is implementing validation features in its linter that support JSON Schema.

Currently, we are extending JSON Schema with special annotations using the x-tombi-* prefix.

Schema Priority

This section explains how Tombi prioritizes the application of x-tombi-* keys in your JSON Schema:

  1. #:schema directive in the TOML file's top comment (compatible with Taplo)
  2. JSON Schema specified in the Tombi configuration file
  3. JSON Schema from the JSON Schema Store

Tombi metadata

Tombi supports the following metadata keys in your JSON Schema.

x-tombi-toml-version

This key automatically determines the TOML version to use. Currently, we support:

  • v1.0.0 (stable)
  • v1.1.0 (latest)

The preview version includes exciting features like trailing comma support in Inline Tables.

🗒️Note

v1.1.0 has only just been released and is not yet supported by many tools. Therefore, v1.0.0 will be used as the default TOML version for the time being.

If you want to use v1.1.0, please specify toml-version = "v1.1.0" in your tombi.toml, or set x-tombi-toml-version = "v1.1.0" in your JSON Schema.

For example, the JSON Schema for tombi.toml specifies v1.1.0.

x-tombi-additional-key-label

This key specifies the label to use for additional keys.

{
  "type": "object",
  "properties": {
    "dependencies": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/definitions/Dependency"
      },
      "x-tombi-additional-key-label": "crate_name",
      ...
    },
    ...
  },
  ...
}

This allows the label displayed in the completion candidates for additionalProperties keys to be $crate_name.
If you don't specify this key, the label will be $key.

Formatting

x-tombi-table-keys-order

This key controls the automatic sorting of table keys (e.g., [dependencies]).

Available sorting strategies:

  • ascending
  • descending
  • version-sort
  • schema
🗒️Note

The version-sort strategy is based on the Rust style guide.

By specifying object instead of string, you can individually define sorting methods for the different groups: properties, additionalProperties, and patternProperties.

{
  "x-tombi-table-keys-order": {
    "properties": "schema",
    "patternProperties": "version-sort",
    "additionalProperties": "descending"
  }
}

The order of the object's properties is significant. Sorting is performed sequentially for each group starting from the first property, and the results are then combined.

🗒️Note

The schema strategy can only be used for properties.

x-tombi-array-values-order

This key controls the automatic sorting of array values.

Available sorting strategies:

  • ascending
  • descending
  • version-sort
🗒️Note

The version-sort strategy is based on the Rust style guide.

⚠️Warning

Float and Array cannot be sorted. To sort Table, you need to use x-tombi-array-values-order-by.

By specifying object instead of string, you can individually define sorting methods for the different groups: oneOf, anyOf.

The following example, sorts the first schema of oneOf with version-sort, and the second schema with ascending after that.

{
  "type": "array",
  "items": {
    "oneOf": [
      { "type": "string" },
      { "type": "number" }
    ]
  },
  "x-tombi-array-values-order": {
    "oneOf": [
      "version-sort",
      "ascending"
    ]
  }
}

The following is the sorting result.

# Before
key = [1, "2", 3, "4"]

# After
key = ["2", "4", 1, 3]
⚠️Warning

oneOf and anyOf cannot sort nested schemas. oneOf and anyOf must be flattened.

{
  "oneOf": [
    {
      // Cannot use nested `oneOf` / `anyOf`
      "oneOf": [
        { "type": "string" },
        { "type": "number" }
      ]
    },
    ...
  ],
  "x-tombi-array-values-order": {
    "oneOf": [...]
  }
}

x-tombi-array-values-order-by

This key specifies which key to use as the sorting key when the array element is a table.

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "name": {
        "type": "string"
      },
      "age": {
        "type": "number"
      }
    },
    "x-tombi-array-values-order-by": "name"
  },
  "x-tombi-array-values-order": "ascending"
}

The following is the sorting result.

# Before
key = [
  { name = "Bob", age = 30 },
  { name = "Charlie", age = 25 },
  { name = "Alice", age = 20 },
]

# After
key = [
  { name = "Alice", age = 20 },
  { name = "Bob", age = 30 },
  { name = "Charlie", age = 25 },
]

Linting

Validation Score

For complex JSON Schemas, validation failures can produce many error messages. To help users identify the most relevant errors, Tombi uses a scoring system to filter out less important validation failures.

The currently implemented points are as follows:

  • Type matching: 1 point is added for the value that matches the type defined in the JSON Schema.
  • Required key matching: 1 point is added for each required key present in the table schema.

More details are here.

Strict Mode

By default, Tombi operates in strict mode. In this mode, objects without additionalProperties are treated as if additionalProperties: false was specified. This differs from the standard JSON Schema specification but provides more precise validation by eliminating ambiguity.

To disable strict mode, add schema.strict = false to your tombi.toml configuration.

x-tombi-string-formats

In Tombi default behavior, the format used in JSON Schema's “type”: “string" only recognizes conversions to the following built-in types:

  • date-time
  • date-time-local
  • date
  • time-local

By adding the x-tombi-string-formats key to the root of the JSON Schema, you can add the format of the string to the validation target.

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "x-tombi-string-formats": [
    "email",
    "hostname",
    "uri",
    "uuid",
    "ipv4",
    "ipv6"
  ]
}

Currently supported format targets are as follows:

formatSpecificationTOML Type
emailRFC 5322
hostnameRFC 1034
uriRFC 3986
uri-referenceRFC 3986
uuidRFC 4122
ipv4RFC 2673 §3.2
ipv6RFC 4291 §2.2
date-timeRFC 3339 §5.6Offset Date-Time
date-time-localOpenAPI Format RegistryLocal Date-Time
dateRFC 3339 §5.6 full-dateLocal Date
timeRFC 3339 §5.6 full-time
time-localOpenAPI Format RegistryLocal Time
regexECMA-262
json-pointerRFC 6901
🗒️Note

If you want to support additional format in Tombi, please check if it exists in JSON Schema Specification or OpenAPI Format Registry.

Language Gap

While TOML and JSON are different languages, JSON Schema remains a valuable tool for representing TOML structures, especially given the abundance of existing schema assets.

Tombi bridges this language gap by using abbreviations to represent JSON Schema concepts that don't have direct equivalents in TOML.

For more details on how Tombi represents these concepts, check out the Hover section.

JSON Catalog/Schema Cache

Tombi caches JSON Catalog/Schemas in the file system to avoid unnecessary network requests.

Cache Expiration

Cached schemas expire after 24 hours by default. When a cached schema expires, Tombi automatically fetches the latest version from the remote source.

You can customize the cache expiration time using the TOMBI_CACHE_TTL environment variable. See Environment Variables for details.

How to Clear Cache

CLI

Use --no-cache option to disable using caches for a CLI command.

tombi format --no-cache
⚠️Warning

--no-cache option does not use caches, but saves the latest catalogs/schemas to the file caches.
(This behavior is the same as HTTP's Cache-Control: no-cache)

It only applies to catalogs/schemas used by the command, and does not update other files.

Language Server

Use RefreshCache command to clear the cache.

⚠️Warning

It removes all file caches and fetches the latest schema over the network for the editing TOML file.

Cache Location Search Priority

  1. $XDG_CACHE_HOME/tombi
  2. ~/.cache/tombi

Associate Schema

VSCode supports associating a TOML schema with a file match pattern. See VSCode Extension for details.

Compliance Status

The table below summarizes keyword membership in each JSON Schema dialect and whether Tombi implements the keyword when that dialect defines it.

: supported in the dialect
: not implemented in Tombi
-: not used by that dialect

Keyworddraft-07draft-2019-09draft-2020-12
$id
$schema
$ref
$defs
definitions--
$anchor-
$dynamicRef--
$dynamicAnchor--
$recursiveRef--
$recursiveAnchor--
$vocabulary-
allOf
anyOf
oneOf
not
if
then
else
properties
patternProperties
additionalProperties
propertyNames
items
additionalItems-
prefixItems--
contains
dependentSchemas-
unevaluatedProperties-
unevaluatedItems-
type
enum
const
multipleOf
maximum
minimum
exclusiveMaximum
exclusiveMinimum
maxLength
minLength
pattern
format
maxItems
minItems
uniqueItems
maxProperties
minProperties
required
dependencies-
dependentRequired-
minContains-
maxContains-
title
description
default
examples
deprecated
$comment
readOnly
writeOnly
contentEncoding
contentMediaType
contentSchema
🗒️Note

Tombi also accepts some legacy keywords for compatibility even when they are not part of the selected dialect. For example, definitions is still loaded alongside $defs in draft-2019-09 and draft-2020-12, dependencies is still honored in draft-2020-12, and prefixItems is accepted even before draft-2020-12.

🗒️Note

format, title, description, default, examples, deprecated, contentEncoding, contentMediaType, and contentSchema are not all treated as pure assertion keywords. Some are used as annotations for validation behavior, hover, completion, or diagnostics.

🗒️Note

Tombi defaults to a non-standard strict behavior: when additionalProperties is omitted, objects are treated as closed unless you disable schema.strict.