Learn R Programming

schemate

A small, checkmate-first schema DSL for R data.

schemate provides a small, checkmate-first schema DSL for R data. It can infer schemas from example objects, edit schema documents, save them as JSON, read them back, and validate new inputs against the schema.

The package is meant for package authors and pipeline authors who want a compact R-native schema format without adopting the full JSON Schema vocabulary. A typical workflow is:

  1. infer a conservative schema with schema_infer();
  2. edit it with schema_*() authoring verbs;
  3. save it with schema_write();
  4. read it back with schema_read();
  5. validate inputs with schema_validate().

Installation

install.packages("schemate")

Development Version

To get a bug fix or to use a feature from the development version, you can install the development version of schemate from GitHub.

# install.packages("pak")
pak::pak("hongyuanjia/schemate")

Quick Start

The public API uses a single schema_ prefix and works well in pipelines. Start from an example object, infer a conservative schema, then compact it into something easier to edit and review.

library(schemate)

payload <- list(
    items = list(
        list(id = 1L, name = "alpha", label = "Alpha", slug = "alpha"),
        list(id = 2L, name = "beta", label = "Beta", slug = "beta")
    )
)

schema <- payload |>
    schema_infer(keys = "named", arrays = "rest") |>
    schema_compact() |>
    schema_set_desc("$items", "Repository-like result items")

schema
## {
##   "check": {
##     "kind": "list"
##   },
##   "keys": {
##     "type": "named"
##   },
##   "fields": {
##     "items": {
##       "description": "Repository-like result items",
##       "check": {
##         "kind": "list"
##       },
##       "keys": {
##         "type": "unnamed"
##       },
##       "rest": {
##         "check": {
##           "kind": "list"
##         },
##         "keys": {
##           "type": "named"
##         },
##         "fields": {
##           "id": {
##             "check": {
##               "kind": "int"
##             }
##           }
##         },
##         "groups": [
##           {
##             "names": ["name", "label", "slug"],
##             "check": {
##               "kind": "string"
##             }
##           }
##         ]
##       }
##     }
##   }
## }
schema |>
    schema_validate(payload, mode = "test")
## [1] TRUE

schema_validate() defaults to assert mode: invalid input raises an error and valid input is returned invisibly. Other modes are available when you need a message or a boolean result.

bad_payload <- payload
bad_payload$items[[1L]]$id <- "bad"

schema |>
    schema_validate(bad_payload, mode = "check", name = "payload")
## [1] "payload$items[[1]]$id: Must be of type 'single integerish value', not 'character'"
schema |>
    schema_validate(bad_payload, mode = "test", name = "payload")
## [1] FALSE

For a data frame example, see the Get started article.

JSON Workflow

Schemas are stored as a compact JSON DSL. The DSL is not JSON Schema; it is a thin representation of checkmate checks, field schemas, local definitions, and combinators. See the Schema DSL article for the complete format reference. schema_read() and schema_write() require the suggested package jsonlite.

path <- tempfile(fileext = ".json")
schema_write(schema, path)

restored <- schema_read(path)
restored
## {
##   "check": {
##     "kind": "list"
##   },
##   "keys": {
##     "type": "named"
##   },
##   "fields": {
##     "items": {
##       "description": "Repository-like result items",
##       "check": {
##         "kind": "list"
##       },
##       "keys": {
##         "type": "unnamed"
##       },
##       "rest": {
##         "check": {
##           "kind": "list"
##         },
##         "keys": {
##           "type": "named"
##         },
##         "fields": {
##           "id": {
##             "check": {
##               "kind": "int"
##             }
##           }
##         },
##         "groups": [
##           {
##             "names": ["name", "label", "slug"],
##             "check": {
##               "kind": "string"
##             }
##           }
##         ]
##       }
##     }
##   }
## }
restored |>
    schema_validate(payload)

Example schema files are installed under inst/extdata:

system.file("extdata", "person-schema.json", package = "schemate")

Validation Modes

schema_validate() supports four modes:

ModeReturn value on successReturn value on failure
assertinvisibly returns the inputthrows an error
checkTRUEdiagnostic string
testTRUEFALSE
expecttestthat-style expectation objectexpectation failure object

Use assert inside application code, check when displaying diagnostics, test for control flow, and expect in tests.

Standalone Use

schemate also publishes a generated standalone bundle for packages that want the schema features without depending on schemate at runtime.

usethis::use_standalone("hongyuanjia/schemate", "schema", ref = "standalone")

Relation to Other Tools

schemate is closest in spirit to checkmate: schemas ultimately validate R objects by calling checkmate checks. It adds a schema lifecycle around those checks: infer, edit, serialize, read, and validate.

pointblank is a better fit for tabular data quality workflows, reporting, and column-oriented validation plans. schemate is deliberately narrower and more structural: it describes R values, R object names, nested lists, JSON-like payloads, and package-facing input contracts. It is not a replacement for JSON Schema or jsonvalidate, which are better choices when you need standards-compliant JSON document validation.

The R validation ecosystem is broad:

  • validate captures data validation rules that can be documented, stored, and applied to data sets.
  • assertr is designed for assertive data checks inside analysis pipelines.
  • data.validator focuses on dataset validation with reporting.
  • vetr provides template-based structural checks for R objects.
  • testthat is the right home for unit-test expectations; schema_validate(..., mode = "expect") is intended to fit into that style.

License

The project is released under the terms of MIT License.

Copy Link

Version

Install

install.packages('schemate')

Version

0.1.0

License

MIT + file LICENSE

Maintainer

Hongyuan Jia

Last Published

June 12th, 2026

Functions in schemate (0.1.0)

schema_one

Create a one schema combinator fragment
schema_paths

Query schema paths and matching nodes
schemate-package

schemate: Checkmate-first schema inference, editing, JSON IO, and validation
schema_check

Create a schema check fragment
schema_del_group

Delete a schema group from a container node
schema_group

Create a schema group fragment
schema_del_rest

Delete a container rest schema
schema_add_def

Add a schema definition
schema_add_field

Add a field schema to a container node
schema_add_group

Add a schema group to a container node
schema_del_def

Delete a schema definition
schema_write

Read and write schema JSON
schema_modify_where

Modify schema nodes selected by a predicate
schema_any

Create an any schema combinator fragment
schema_del_field

Delete a field schema from a container node
schema_del_position

Delete a position schema from an unnamed container node
schema_del_keys

Delete a schema node keys rule
schema_doc

Parse schema documents
schema_all

Create an all schema combinator fragment
schema_add_position

Add a position schema to an unnamed container node
schema_compact

Compact a schema document
schema_infer

Infer a conservative schema from example data
schema_where_path

Create schema query predicates
schema_set_desc

Set or remove a schema node description
schema_not

Create a not schema combinator fragment
schema_set_keys

Set a schema node keys rule
schema_set_rest

Set or replace a container rest schema
schema_validate

Validate input against a schema
schema_ref

Create a schema reference fragment
schema_replace

Replace a schema node