JSON Schema Forms

Add $schema to your data. Get a free edit form.

How it works

Add a $schema property to your JSON-LD data pointing to a JSON Schema file:

{
  "@context": { "title": "http://purl.org/dc/terms/title" },
  "@id": "#this",
  "@type": "Tracker",
  "$schema": "my-schema.json",
  "title": "My Tasks"
}

Include the schema pane in your HTML:

<script type="module" data-pane src="panes/schema-pane.js"></script>

That's it. An "Edit" tab appears with auto-generated form fields.

What gets generated

Schema typeForm element
stringText input
string with long maxLengthTextarea
number / integerNumber input with min/max
booleanCheckbox
enumDropdown select
array of objectsRepeatable fieldset with add/remove

Properties starting with @ or $ are hidden from the form.

Validation

Fields are validated as you type:

Errors show inline under the field. The store still saves — validation is advisory, not blocking.

Example schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "My App",
  "description": "Edit your app data",
  "type": "object",
  "required": ["title"],
  "properties": {
    "title": {
      "type": "string",
      "minLength": 1,
      "description": "The name of your app"
    },
    "status": {
      "type": "string",
      "enum": ["draft", "published", "archived"],
      "description": "Current status"
    },
    "priority": {
      "type": "integer",
      "minimum": 1,
      "maximum": 5,
      "description": "Priority level"
    },
    "published": {
      "type": "boolean",
      "description": "Whether this is public"
    },
    "items": {
      "type": "array",
      "title": "Items",
      "description": "List of items",
      "items": {
        "type": "object",
        "properties": {
          "@id": { "type": "string" },
          "@type": { "const": "Item" },
          "name": { "type": "string", "description": "Item name" },
          "done": { "type": "boolean" }
        }
      }
    }
  }
}

$ref support

The schema pane resolves $ref pointers to $defs and definitions:

{
  "properties": {
    "items": {
      "type": "array",
      "items": { "$ref": "#/$defs/item" }
    }
  },
  "$defs": {
    "item": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "status": { "type": "string", "enum": ["todo", "done"] }
      }
    }
  }
}

Schema URL resolution

The $schema URL is resolved relative to the data file, not the page. So if your data is at data/tasks.jsonld with "$schema": "tasks-schema.json", the pane fetches data/tasks-schema.json.

Completely optional

The schema pane is opt-in at two levels:

No $schema in the data? No tab. No schema pane in the HTML? No effect. Zero impact on apps that don't use it.

Live demo

See it in action: losos.org/todo/ — click the "Edit" tab. The form is generated from todo-schema.json.