$ref and $defs — Reusable Schema Definitions

Use $ref and $defs in JSON Schema to create reusable definitions. Eliminate duplication by extracting shared sub-schemas and referencing them across your schema.

Advanced Patterns

Detailed Explanation

Reusable Schemas with $ref and $defs

As schemas grow, the same structure often appears in multiple places. The $ref keyword lets you reference a shared definition instead of duplicating it.

Basic $defs and $ref

{
  "$defs": {
    "address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" },
        "zip": { "type": "string" }
      },
      "required": ["street", "city"]
    }
  },
  "type": "object",
  "properties": {
    "billing": { "$ref": "#/$defs/address" },
    "shipping": { "$ref": "#/$defs/address" }
  }
}

Both billing and shipping share the same address schema. Changes to the address definition automatically apply everywhere it is referenced.

How References Work

  • $ref uses a JSON Pointer to locate the target schema. #/$defs/address means "start at the root (#), navigate to $defs, then to address."
  • $defs is the standard location for reusable definitions in Draft 2020-12. Older drafts used definitions (without the $ prefix).
  • A $ref replaces the entire schema at that location. In older drafts, sibling keywords next to $ref were ignored. In Draft 2020-12, sibling keywords are applied.

External References

References can point to external files:

{ "$ref": "https://example.com/schemas/address.json" }

or relative paths:

{ "$ref": "./common/address.json" }

Generator Behavior

Most generators produce fully inline schemas by default. To leverage $ref:

  1. Generate the initial schema from your JSON sample.
  2. Identify duplicated sub-schemas (e.g., address, timestamps, user objects).
  3. Extract them into $defs and replace the inline definitions with $ref pointers.

Some advanced generators detect repeated structures and emit $ref automatically.

Recursive Schemas

$ref enables recursive structures — a schema that references itself:

{
  "$defs": {
    "node": {
      "type": "object",
      "properties": {
        "value": { "type": "string" },
        "children": {
          "type": "array",
          "items": { "$ref": "#/$defs/node" }
        }
      }
    }
  },
  "$ref": "#/$defs/node"
}

This models a tree structure where each node can have child nodes of the same shape.

Use Case

Use $ref and $defs when your schema contains repeated structures like addresses, user objects, or error responses. This is especially valuable in large OpenAPI specifications where dozens of endpoints share common models.

Try It — JSON Schema Generator

Open full tool