Every SvelteKit form action, remote function and API route needs the same thing before it touches data: a schema that says what a valid request looks like. In a plain SvelteKit project that means opening src/lib/schemas/, writing a z.object() by hand, and keeping it in sync with the database column it validates. The vela generate schema generator does the writing from a one-line description of the model.
Prerequisites
Any SvelteKit project. The generator needs no vela setup, no backend and no component kit, so a fresh one is enough:
Run vela with npx vela, or add it to the project with npm install -D vela. If the project has no zod yet, the command installs it alongside the schema.
A project made with npx vela create my-app, or upgraded with npx vela bless, already has Zod and Superforms, which the first example under “Use it” relies on. Coming from vanilla SvelteKit explains what bless adds and what it leaves alone.
Run the command
A schema is a model name followed by fields. Each field is name:type, and a trailing ! makes it required:
What was generated
One file. The model name becomes the file name and the export name:
import { z } from "zod";
export const loginSchema = z.object({
email: z.email(),
password: z.string().nonempty(),
});
The highlighted lines are the two fields you described. email:email! became z.email(), and password:text! became a non-empty string. Every field type in the generator syntax has a Zod equivalent, so age:number gives you z.number(), role:select(admin:Admin,member:Member) gives you an enum, and a field without ! is wrapped in .optional().
Use it
The schema is plain Zod, so it works anywhere Zod does. In a form action with Superforms:
import { superValidate } from 'sveltekit-superforms';
import { zod4 } from 'sveltekit-superforms/adapters';
import { loginSchema } from '$lib/schemas/login';
export const load = async () => ({ form: await superValidate(zod4(loginSchema)) });Or on its own, in a +server.ts endpoint:
import { json } from '@sveltejs/kit';
import { loginSchema } from '$lib/schemas/login';
export const POST = async ({ request }) => {
const body = loginSchema.parse(await request.json());
return json({ ok: true, email: body.email });
};vela generate form instead. It generates the same schema plus the page, the handler and a server test.Change your mind
Generated files are ordinary source, so you can edit the schema by hand. If you would rather start over, remove it with the matching destroy command:


