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.
- π« No more runtime content errors β Catch validation issues at build time
- π Framework agnostic β Works seamlessly with Astro, Next.js, Remix, SvelteKit, and more
- π Standard Schema compliant β Built on Standard Schema v1 for maximum interoperability
- β‘ Performance first β <50ms validation per document, handles 5000+ files efficiently
- π οΈ Developer friendly β Excellent TypeScript support with comprehensive error messages
- π§ Zero config β Works out of the box, customizable when you need it
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 β Validate markdown files against custom schemas with detailed error reporting
π― Standard Schema β Built on Standard Schema for interoperability
ποΈ Framework Integration β Works seamlessly with Astro, Next.js, and other modern frameworks
π Schema Registry β Reuse and manage validation schemas across projects
π Markdown Processing β Parse and serialize markdown with frontmatter
π€ AI Workflows β Model Context Protocol (MCP) server for AI-powered content validation
π οΈ Biome Plugins β Custom GritQL linting rules for migration assistance and best practices
npm install @watthem/fieldtest
# or
pnpm add @watthem/fieldtest
# or
yarn add @watthem/fieldtestRequirements: Node.js 18+ | Works with any package manager
- Define your content schema:
import type { StandardSchemaV1 } from '@watthem/fieldtest';
const blogSchema: StandardSchemaV1 = {
version: '1',
name: 'blog-post',
fields: {
title: { type: 'string', required: true },
author: { type: 'string', required: true },
published: { type: 'boolean', required: true },
tags: { type: 'string', array: true },
publishedAt: { type: 'date', required: false }
}
};- Validate your markdown content:
import { loadUserSchema, validateWithSchema } from '@watthem/fieldtest';
const schema = loadUserSchema(blogSchema);
const markdown = `---
title: "Getting Started with FieldTest"
author: "Jane Developer"
published: true
tags: ["typescript", "validation", "markdown"]
---
# Getting Started
This post shows how easy it is to validate content with FieldTest!
`;
const result = validateWithSchema(markdown, schema);
if (result.valid) {
console.log('β Content validated successfully!');
// Your content is safe to use
} else {
console.error('β Validation failed:');
result.errors.forEach(error => {
console.error(` β’ ${error.field}: ${error.message}`);
});
}That's it! You're now validating content like a pro. π
FieldTest works seamlessly with your favorite framework:
// src/content/config.ts
import { defineCollection } from 'astro:content';
import { loadUserSchema, validateWithSchema } from '@watthem/fieldtest';
const blog = defineCollection({
type: 'content',
schema: (z) => z.object({
title: z.string(),
author: z.string(),
publishedAt: z.date()
}).refine((data) => {
// Add FieldTest validation on top of Zod
const result = validateWithSchema(
generateMarkdown(data),
loadUserSchema(blogSchema)
);
return result.valid;
})
});// Validate content in getStaticProps, generateStaticParams, or API routes
import { validateWithSchema, loadUserSchema } from '@watthem/fieldtest';
import fs from 'fs';
export async function generateStaticParams() {
const schema = loadUserSchema(blogSchema);
const posts = fs.readdirSync('./content');
return posts.map(post => {
const content = fs.readFileSync(`./content/${post}`, 'utf-8');
const result = validateWithSchema(content, schema);
if (!result.valid) {
throw new Error(`Invalid post ${post}: ${result.errors.map(e => e.message).join(', ')}`);
}
return { slug: post.replace('.md', '') };
});
}// Works with Remix, SvelteKit, Nuxt, Solid, and more!
import { validateWithSchema } from '@watthem/fieldtest';
// Universal validation that works anywhere
const isValid = validateWithSchema(content, schema).valid;Skip writing schemas for common use cases:
import { getBuiltInSchema } from '@watthem/fieldtest';
// Pre-built schemas for common content types
const blogSchema = getBuiltInSchema('blog-post');
const docsSchema = getBuiltInSchema('documentation');
const marketingSchema = getBuiltInSchema('marketing-copy');FieldTest includes custom GritQL plugins for Biome to help with migration and best practices:
// biome.json
{
"plugins": [
"./node_modules/@watthem/fieldtest/grit-plugins/fieldtest-migration.grit",
"./node_modules/@watthem/fieldtest/grit-plugins/schema-usage.grit"
]
}- βοΈ Migration Helper β Detects legacy imports and types
- β Schema Validation β Ensures validation results are checked
- π¨ Code Quality β Flags non-standard patterns
// AI-powered content validation and generation
import { MCPServer } from '@watthem/fieldtest/mcp';
const server = new MCPServer({
schemas: [blogSchema, docsSchema],
aiValidation: true
});FieldTest has comprehensive documentation to get you started:
- π Getting Started β Quick installation and first steps
- π API Reference β Complete function and type documentation
- π― Framework Guides β Astro, Next.js, and more
- π Schema Validation Guide β Creating and using schemas
- π« Examples β Real-world use cases and patterns
We welcome contributions! FieldTest is open source and built by the community.
# Clone and setup
git clone https://github.com/watthem/fieldtest.git
cd fieldtest
pnpm install
# Start development
pnpm dev # Watch mode for all packages
pnpm test # Run tests
pnpm lint # Check code quality- π Report bugs or request features via GitHub Issues
- π Improve documentation β Fix typos, add examples, clarify concepts
- π οΈ Add features β New schema types, framework integrations, utilities
- πΊ Create examples β Show how to use FieldTest in different scenarios
- π Build integrations β Plugins for editors, build tools, or frameworks
Check out our Contributing Guide for detailed guidelines.
Upgrading from FKit or legacy @fieldtest/* packages? We've got you covered:
# Update package.json
npm uninstall @fieldtest/core @fieldtest/validate @fieldtest/registry
npm install @watthem/fieldtest
# Update imports (TypeScript/JavaScript)
find . -name "*.ts" -o -name "*.tsx" -o -name "*.js" | xargs sed -i 's/@fieldtest\/[a-zA-Z-]*/@watthem\/fieldtest/g'
find . -name "*.ts" -o -name "*.tsx" -o -name "*.js" | xargs sed -i 's/FkitDocument/FieldTestDocument/g'π Complete Migration Guide β Detailed migration steps and breaking changes
Join the FieldTest community:
- π GitHub Issues β Bug reports and feature requests
- π¬ GitHub Discussions β Questions, ideas, and showcase
- π¦ Twitter β Updates and announcements
- π§ Email β Direct contact for partnerships or support
MIT License Β© 2024 Matthew Hendricks
Free to use in personal and commercial projects. See LICENSE for details.
FieldTest stands on the shoulders of giants:
- π¦ Standard Schema β Universal validation interface
- βοΈ TypeScript β Type-safe development experience
- π¦ pnpm + Turborepo β Fast, reliable monorepo management
- π€ Biome β Fast formatting and linting
- β‘ Vitest β Blazing fast unit testing
Ready to validate your content like a pro?
Get Started β’ See Examples β’ Star on GitHub