Import JSON Schemas into TypeScript. Fully typed, scary fast.
If you have a JSON Schema like this:
You can import it directly from a TypeScript file, and get its type and a validator:
// main.ts
import user from "./user.schema.jsonc";
const data = await request.json();
if (user.is(data)) {
data; // { name: string; role?: "admin" | "member" }
}It's powered by TypeScript's content mappers (introduced in TypeScript 7.1), which let a package give tsc the types of a file it imports. The validator is compiled by ajv when the module is built, so a bundle carries the validator and no validator library.
You'll need TypeScript 7.1 (currently in beta) and Node 24 or later:
npm install -D dotschema typescript@betaAn app that runs under the preload, not as a bundle, builds each schema's module at run time, so it installs dotschema as a dependency: npm install dotschema.
Add dotschema to tsconfig.json as a content mapper:
// tsconfig.json
{
"compilerOptions": { /* ... */ },
"contentMappers": [
{ "package": "dotschema", "extensions": [".schema.jsonc"] }
]
}Then type-check with --runExternalCode, which lets tsc run content mappers:
// package.json
{
"scripts": {
"typecheck": "tsc --noEmit --runExternalCode"
}
}Load dotschema wherever your code runs, so that a schema import works at run time too:
| Runtime or bundler | Setup |
|---|---|
| Node | node --import dotschema/register main.ts (setup) |
| Bun | preload = ["dotschema/register"] in bunfig.toml (setup) |
| nub | "preload": ["dotschema/register"] in nub.jsonc (setup) |
| Vite, Vitest, Rollup, Rolldown | import dotschema from "dotschema/vite", then dotschema() in plugins (setup) |
| Next.js | import { withDotschema } from "dotschema/next", then export default withDotschema(nextConfig) (setup) |
esbuild, Bun.build |
import dotschema from "dotschema/esbuild", then dotschema() in plugins (setup) |
| webpack, Rspack | use: "dotschema/webpack" in a rule for the schema files, in module.rules (setup) |
| Cloudflare Workers | dotschema's Vite plugin beside Cloudflare's (setup) |
| Jest | "dotschema/jest" in transform, for the schema files (setup) |
Your editor types schema imports through the TypeScript 7.1 language server, with content mappers on: in VS Code and Cursor, the TypeScript 7 extension pointed at your project's TypeScript, and in Zed, the TypeScript Language Server extension. The settings for each are in Editors.
The rest is on dotschema.dev:
- Usage:
.validate(), with defaults, transforms and unlisted keys,.is(), the types.outputand.input,.pick(),.omit(),.partial(),.required()and.keyof(), definitions, and Standard Schema - Inference: the type each shape of schema gives, a
$refto another file, and every format the validator checks - Doc comments: a schema's comments,
descriptionand tags on the type - Errors: an invalid schema as a type error, and a message of the schema's own
- Reference: what every keyword does to the type, and the drafts
- FAQ
MIT