{}OPF
DocsHow-to

Validate OPF files

Every OPF pipeline should validate documents against the canonical JSON Schema before rendering. Here are three ways to do it.

Get the schema

The canonical OPF v1 JSON Schema is served at https://openpresentation.org/schema/opf/v1 — the same URL every deck references in its $schema field. Fetch it once and validate locally:

shell
curl -sL https://openpresentation.org/schema/opf/v1 -o opf.schema.json

A browsable version with field-by-field documentation is at the OPF schema reference.

Ajv in Node.js

Ajv is the standard JSON Schema validator for JavaScript. Install ajv and ajv-formats, then:

validate.ts
import Ajv from "ajv"
import addFormats from "ajv-formats"
import { readFileSync } from "node:fs"

const schema = JSON.parse(readFileSync("opf.schema.json", "utf8"))
const deck = JSON.parse(readFileSync("deck.opf.json", "utf8"))

const ajv = new Ajv({ allErrors: true })
addFormats(ajv)

const validate = ajv.compile(schema)

if (validate(deck)) {
  console.log("Valid OPF document")
} else {
  console.error(validate.errors)
  process.exit(1)
}

ajv-cli

Validate from a terminal or script without writing any code:

shell
npx ajv-cli validate -s opf.schema.json -d deck.opf.json --spec=draft2020 -c ajv-formats

The OPF package

The @openpresentation/opf package bundles the schema and exposes a validatePresentationhelper, so you don't need to fetch the schema separately:

validate-with-package.ts
import { validatePresentation } from "@openpresentation/opf"
import { readFileSync } from "node:fs"

const deck = JSON.parse(readFileSync("deck.opf.json", "utf8"))
const result = validatePresentation(deck)

if (!result.valid) {
  console.error(result.errors)
  process.exit(1)
}

Newer versions of the validator also return a separate warnings array for advisory issues, such as references to unknown catalog ids. Warnings never affect valid — treat them as hints, not failures. Check the developer docs for the package's current publication status.

Validate in CI

If decks live in your repository, validate them on every push so invalid documents never reach a renderer:

validate-decks.yml
# .github/workflows/validate-decks.yml
name: Validate OPF decks
on: [push, pull_request]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: curl -sL https://openpresentation.org/schema/opf/v1 -o opf.schema.json
      - run: |
          shopt -s nullglob
          for deck in decks/*.opf.json; do
            npx ajv-cli validate -s opf.schema.json -d "$deck" --spec=draft2020 -c ajv-formats
          done