docs/schema-validation.html
On this page
RxDB has multiple validation implementations that can be used to ensure that your document data is always matching the provided JSON schema of your RxCollection.
The schema validation is not a plugin but comes in as a wrapper around any other RxStorage and it will then validate all data that is written into that storage. This is required for multiple reasons:
warning
Schema validation can be CPU expensive and increases your build size. You should always use a schema validation in development mode. For most use cases, you should not use a validation in production for better performance.
When no validation is used, any document data can be saved but there might be undefined behavior when saving data that does not comply to the schema of a RxCollection.
RxDB has different implementations to validate data, each of them is based on a different JSON Schema library. In this example we use the LocalStorage RxStorage, but you can wrap the validation around any other RxStorage.
A validation-module that does the schema-validation. This one is using ajv as validator which is a bit faster. Better compliant to the jsonschema-standard but also has a bigger build-size.
import { wrappedValidateAjvStorage } from 'rxdb/plugins/validate-ajv';
import { getRxStorageLocalstorage } from 'rxdb/plugins/storage-localstorage';
// wrap the validation around the main RxStorage
const storage = wrappedValidateAjvStorage({
storage: getRxStorageLocalstorage()
});
const db = await createRxDatabase({
name: randomCouchString(10),
storage
});
Both is-my-json-valid and validate-ajv use eval() to perform validation which might not be wanted when 'unsafe-eval' is not allowed in Content Security Policies. This one is using z-schema as validator which doesn't use eval.
import { wrappedValidateZSchemaStorage } from 'rxdb/plugins/validate-z-schema';
import { getRxStorageLocalstorage } from 'rxdb/plugins/storage-localstorage';
// wrap the validation around the main RxStorage
const storage = wrappedValidateZSchemaStorage({
storage: getRxStorageLocalstorage()
});
const db = await createRxDatabase({
name: randomCouchString(10),
storage
});
WARNING : The is-my-json-valid validation is no longer supported until this bug is fixed.
The validate-is-my-json-valid plugin uses is-my-json-valid for schema validation.
import {
wrappedValidateIsMyJsonValidStorage
} from 'rxdb/plugins/validate-is-my-json-valid';
import { getRxStorageLocalstorage } from 'rxdb/plugins/storage-localstorage';
// wrap the validation around the main RxStorage
const storage = wrappedValidateIsMyJsonValidStorage({
storage: getRxStorageLocalstorage()
});
const db = await createRxDatabase({
name: randomCouchString(10),
storage
});
The schema validators provide methods to add custom formats like a email format. You have to add these formats before you create your database.
import { getAjv } from 'rxdb/plugins/validate-ajv';
const ajv = getAjv();
ajv.addFormat('email', {
type: 'string',
validate: v => v.includes('@') // ensure email fields contain the @ symbol
});
import { ZSchemaClass } from 'rxdb/plugins/validate-z-schema';
ZSchemaClass.registerFormat('email', function (v: string) {
return v.includes('@'); // ensure email fields contain the @ symbol
});
The RxDB team ran performance benchmarks using two storage options on an Ubuntu 24.04 machine with Chrome version 131.0.6778.85. The testing machine has 32 core 13th Gen Intel(R) Core(TM) i9-13900HX CPU.
IndexedDB Storage (based on the IndexedDB API in the browser):
Loading chart...
Memory Storage: stores everything in memory for extremely fast reads and writes, with no persistence by default. Often used with the RxDB memory-mapped plugin that processes data in memory and later persists to disc in background:
Loading chart...
Including a validator library also increases your JavaScript bundle size. Here's how it breaks down (minified + gzip):
| Build Size (minified+gzip) | Build Size (IndexedDB) | Build Size (memory) |
|---|---|---|
| no validator | 73103 B | 39976 B |
| ajv | 106135 B | 72773 B |
| z-schema | 125186 B | 91882 B |
#What is schema validation and does ajv-formats use eval internally?
Schema validation structurally guarantees that all document mutations strictly comply with the statically defined RxCollection JSON Schema format before data is physically committed to the underlying RxStorage. Yes, both ajv (via ajv-formats) and is-my-json-valid rely natively on eval() or new Function() during compilation to aggressively optimize their validation runtimes. If your deployment environment enforces extremely strict unsafe-eval Content Security Policies (CSP), you must explicitly swap the validator wrapper to validate-z-schema , which strictly avoids eval() at the cost of marginally slower execution.