A validation toolkit for Markdown and Standard Schema — built for Astro, Next.js, and modern frameworks.
FieldTest is a framework-agnostic TypeScript validation toolkit that brings order to content chaos. Whether you're building with Astro, Next.js, or any modern framework, FieldTest ensures your markdown content and frontmatter data is consistent, valid, and production-ready.
- Catch validation issues at build time
- Works across Astro, Next.js, Remix, SvelteKit, and more
- Built on Standard Schema v1
- Fast validation for large content sets
- Strong TypeScript support with clear errors
- Sensible defaults with easy customization
fieldtest/
├── packages/
│ ├── core/ # Core markdown processing
│ ├── validate/ # Validation utilities
│ ├── registry/ # Schema registry
│ ├── shared/ # Common utilities and types
│ ├── examples/ # Example implementations
│ └── integrations/
│ └── mcp/
│ └── fieldtest-mcp-server/ # MCP server for AI workflows
├── grit-plugins/ # Biome GritQL linting plugins
├── docs/ # Documentation
│ ├── guides/ # How-to guides
│ ├── reference/ # API reference
│ └── explainers/ # Conceptual articles
├── scripts/ # Build and utility scripts
└── biome.json # Biome configuration
- Content validation for markdown + frontmatter
- Standard Schema compatibility
- Framework integrations for Astro and Next.js
- Schema registry and reusable validators
- OpenAPI helpers
- Markdown parsing + serialization
- MCP server for AI workflows
- Biome plugins for linting/migration
import { loadOpenApiSchemas } from "@fieldtest/openapi";
import { validate } from "@fieldtest/validation-lib";
const registry = loadOpenApiSchemas("./openapi.yaml");
const createUser = registry.paths["/users"].post;
const [ok] = validate(createUser.requestBody!, { name: "Ada" });npm install @fieldtest/core
# or
pnpm add @fieldtest/coreimport { loadUserSchema, parseMarkdown, validateWithSchema, z } from "@fieldtest/core";
const blogSchema = z.object({
title: z.string(),
date: z.string(),
tags: z.array(z.string()).optional(),
});
const schema = loadUserSchema(blogSchema);
const doc = parseMarkdown(`---\ntitle: Hello\ndate: 2025-01-01\n---\nContent`);
const result = await validateWithSchema(schema, doc.frontmatter, { throwOnError: true });- Docs hub: https://docs.matthewhendricks.net/fieldtest/
- Issues: https://github.com/watthem/fieldtest/issues
MIT