Framework-agnostic

Turn any OpenAPI specinto a typed TypeScript SDK.

One command. Full type safety. Zero config. No Java runtime. Works with any backend — FastAPI, NestJS, Rails, Go, or anything with an OpenAPI spec.

$ npx @vertz/openapi generate --from ./openapi.json
Generated 12 files in ./src/generated, 12 written

Features

Your spec already defines the contract.

The generator reads it, produces a typed SDK, and keeps it in sync. No manual wiring.

01

Every response typed. Every request validated.

The generated SDK infers types directly from your OpenAPI spec. Response bodies, request inputs, query params — all fully typed. Returns FetchResponse<T> with error-as-value pattern via isOk/isErr.

// Generated from your OpenAPI spec
import { createClient } from './generated/client';
import { isOk } from '@vertz/fetch';
const api = createClient({ baseURL: 'https://...' });
const result = await api.tasks.list();
if (isOk(result)) {
console.log(result.data);
// ^? Task[] — fully typed
}
await api.tasks.create({ title: 'Ship it' });
// ^? CreateTaskInput

02

Security schemes become typed auth strategies.

OpenAPI security schemes — bearer, basic, apiKey, OAuth2 — are parsed and wired into the generated client as typed ClientAuth. No manual auth setup. Just pass credentials, headers are set automatically.

// Your spec defines: securitySchemes.bearerAuth
// Generated client includes typed auth:
const api = createClient({
baseURL: 'https://api.example.com',
auth: { bearerAuth: 'my-jwt-token' },
// ^? ClientAuth — typed from your spec
});
// Auth headers set automatically on every request
const tasks = await api.tasks.list();
// → Authorization: Bearer my-jwt-token

03

Zod schemas from your spec. Opt-in.

Pass --schemas and get Zod validation schemas generated alongside your types. Validate user input before it hits the API. Catch bad data at the boundary, not in production.

// Generated with: npx @vertz/openapi generate --schemas
import { createTaskSchema } from './generated/schemas/tasks';
const parsed = createTaskSchema.parse(userInput);
// ^? { title: string; done?: boolean }
// Catches invalid data before it hits your API
createTaskSchema.parse({ title: 123 });
// ✗ ZodError: Expected string, received number

04

FastAPI, NestJS, Rails — or anything with a spec.

Built-in adapters handle operationId quirks for common frameworks. Or point at any OpenAPI 3.x spec — JSON or YAML, file or URL. The generator normalizes everything into clean method names.

// openapi.config.ts — FastAPI backend
import { fastapi } from '@vertz/openapi/adapters';
export default defineConfig({
source: 'https://api.example.com/openapi.json',
operationIds: fastapi(),
});
// openapi.config.ts — NestJS backend
import { nestjs } from '@vertz/openapi/adapters';
export default defineConfig({
source: './openapi.json',
operationIds: nestjs(),
});

05

API changed? TypeScript catches it.

Re-run the generator after a spec update. TypeScript immediately flags every call site that needs updating. Breaking changes caught at compile time — not at 3 AM in production.

// API added a required field: "priority"
$ npx @vertz/openapi generate --from ./openapi.json
// TypeScript immediately catches the gap:
await api.tasks.create({ title: 'Ship it' });
// ✗ Property 'priority' is missing in type
// '{ title: string }' but required in type
// 'CreateTaskInput'.

Why generate?

Zero-config generation

No Java runtime. No YAML templates. No plugin system to learn. Point at a spec, get a typed SDK. One dependency, one command.

Incremental & non-destructive

Only writes files that actually changed (SHA-256 comparison). Cleans up stale files automatically. Safe to run on every CI build.

Agent-ready

Feed the generated SDK to an LLM agent. It gets autocomplete, type errors, and validated inputs. No hallucinated endpoints. No wrong parameter names.

Before / After

Stop writing boilerplate.

Replace hand-written fetch calls with a generated, typed SDK — fewer lines, full type safety, built-in auth.

Before

// Hand-written fetch
const res = await fetch(
'https://api.example.com/tasks'
{ method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
},
body: JSON.stringify({ title: 'Ship it' }),
}
);
const data = await res.json();
// ^? any 😬

After

// Generated SDK
const api = createClient({
baseURL: 'https://api.example.com',
auth: { bearerAuth: token },
});
const result = await api.tasks.create({
title: 'Ship it',
});
// ^? FetchResponse<Task>
// Typed, with retries & error handling

Get started in one command.

Point at your OpenAPI spec. Get a typed SDK. No install required — npx runs it directly.

$ npx @vertz/openapi generate --from ./openapi.json
Generated 12 files in ./src/generated, 12 written