Getting started
Install EDcheck and validate your first form in three simple steps.
EDcheck checks whether your data makes sense. Not only whether it has the right shape.
Zod tells you: “this is an 8-letter string”. That is fine. But Zod also accepts asdfasdf as if it were a name. EDcheck tells you: “that does not look like a person’s name”.
What you need
- Node 20 or newer
- Zod 4 (install it with EDcheck if you do not have it yet)
- A TypeSafe API key, or a Vercel AI Gateway key
Install
yarn add @edteam/edcheck zodThe idea in 3 steps
- 1
Write your Zod schema
Same as always. This file is safe to use in the browser.
- 2
On the server, attach the rules
That is where you use
createEDcheckandsemantic(). Do not put this in the browser. - 3
Call `safeParse`
You get whether it passed, the clean data, and the list of problems.
Step 1. The Zod schema
This file only has Zod. Do not import @edteam/edcheck here. That way you can use it on the client and on the server.
import { z } from "zod"; export const User = z.object({ fullName: z.string().min(2).max(100), bio: z.string().min(10).optional(),});Step 2. Rules on the server
Here you create EDcheck, give it a provider (who talks to the AI), and bind the rules to your schema.
import { createEDcheck, semantic, typesafeProvider } from "@edteam/edcheck"; import { User } from "../shared/user"; const edcheck = createEDcheck({ provider: typesafeProvider({ apiKey: process.env.TYPESAFE_API_KEY!, }),}); export const UserSemantic = edcheck.define(User, { rules: { fullName: semantic("A plausible full name for a real person"), bio: semantic({ intent: "A meaningful professional biography", valid: "Describes the person's work or background", invalid: "Meaningless text or something clearly unrelated", severity: "warning", }), },});semantic("some text") is the shortest form. It is a yes/no question: does this value match that?
Step 3. Validate the data
In your API (for example a Next.js route) you read the JSON and call safeParse.
import { UserSemantic } from "../../../server/user-semantic"; export async function POST(request: Request): Promise<Response> { const input = await request.json(); const result = await UserSemantic.safeParse(input, { signal: request.signal, }); return Response.json(result);}result always looks like this:
success:trueif there is no serious errordata: the data cleaned by Zod, if the shape passedissues: the list of problems (Zod first, then EDcheck)
It only runs on the server
If you call createEDcheck or safeParse in the browser, EDcheck throws EDcheckEnvironmentError. That is on purpose: the AI key must not go to the client.
In the browser, keep using Zod. On the server, use Zod + EDcheck.
What is next
You now have the smallest example. The next page explains, slowly, what each part does.