Getting started
Install one generator, let init write its configuration, run it against a small specification and use what it produced. This page is for developers adding a @spartaficial generator to a TypeScript project for the first time. It uses @spartaficial/openapi-to-zod as the running example; the other generators are installed and run in exactly the same way, and the places where their questions differ are called out.
Install a generator
npm install --save-dev @spartaficial/openapi-to-zod zod
zod is a peer dependency: the schemas the generator writes import it, so it has to be in your own project. Each generator declares the peers its output needs, and nothing else:
| Generator | Install |
|---|---|
@spartaficial/openapi-to-typescript | npm install --save-dev @spartaficial/openapi-to-typescript |
@spartaficial/openapi-to-zod | npm install --save-dev @spartaficial/openapi-to-zod zod |
@spartaficial/openapi-to-zod-playwright | npm install --save-dev @spartaficial/openapi-to-zod-playwright @playwright/test zod |
@spartaficial/openapi-to-k6 | npm install --save-dev @spartaficial/openapi-to-k6 @types/k6 |
Node.js 20 or later is required. requirements.md lists the supported versions of Node.js, Zod and Playwright.
Create a configuration
Every generator has an init command. It asks a few questions and writes <generator>.config.ts (or .json) into the current directory; a licence key is not needed for this step.
npx openapi-to-zod init
The questions, in order:
| Question | Default | What it does |
|---|---|---|
| Overwrite the existing config file? | no | Asked only when openapi-to-zod.config.ts or .json already exists. Answering no cancels. |
| Select OpenAPI spec file (YAML or JSON) | first file found | Lists the .yaml, .yml and .json files under a spec/ or specs/ folder, with their sizes, plus an "Enter manually..." choice. When no such folder exists you type the path straight away; it must exist. |
| Output TypeScript file path | src/schemas.ts | Where the schemas are written. The directory is created on the first run. |
| Config file format | TypeScript (recommended) | TypeScript gives you type checking and autocompletion through defineConfig; JSON needs no imports. See concepts/configuration-files.md. |
| Include commonly-used recommended defaults? | yes | Writes a defaults block that spells out the generator's own defaults, so the choices are visible in the file and easy to change. |
With the defaults included, the file it writes is:
import { defineConfig } from "@spartaficial/openapi-to-zod";
export default defineConfig({
defaults: {
mode: "strict",
includeDescriptions: true,
useDescribe: false,
showStats: true,
schemaType: "all",
},
specs: [
{
input: "specs/openapi.yaml",
outputTypes: "src/schemas.ts",
},
],
});
specs lists the specifications to generate from, each with its input and output paths. defaults holds options every entry inherits; an entry can override any of them. Every option the zod generator accepts is listed in reference/options-zod.md.
The other generators ask the same spec-file and format questions and add their own:
openapi-to-typescript initasks for the types file (src/types.ts) and the enum format (union,enumorconst-object). See generators/typescript.md.openapi-to-zod-playwright initasks for the schemas file (tests/schemas.ts), the client file (tests/client.ts) and an optional service file. See generators/zod-playwright.md.openapi-to-k6 initasks for the client file (k6/api-client.ts), the types file (k6/api-types.ts) and whether to name methods afteroperationId. See generators/k6.md.
Run the generator
Running the command without a subcommand reads the configuration and generates every entry in specs:
npx openapi-to-zod
Licensed to <your organisation> — expires 2027-04-01
Executing 1 specification(s) in parallel (batch size: 10)...
Processing [1/1] specs/openapi.yaml...
✓ Generated src/schemas.ts
==================================================
Batch Execution Summary
==================================================
Total specs: 1
Successful: 1
Failed: 0
==================================================
The first line confirms which licence the run used. The rest is the batch report: one Processing line per entry, then a summary. When an entry fails, the others still run, the failure is listed under the summary and the command exits with status 1, so a CI job notices. To use a configuration file that lives elsewhere or has another name, pass -c (--config):
npx openapi-to-zod --config config/openapi-to-zod.config.ts
What was generated
The example specification is small:
openapi: 3.0.0
info:
title: Simple Test API
version: 1.0.0
components:
schemas:
User:
type: object
description: A user in the system
properties:
id:
type: string
format: uuid
description: The unique identifier for the user
name:
type: string
description: The user's full name
email:
type: string
format: email
description: The user's email address
age:
type: integer
description: The user's age in years
required:
- id
- name
Status:
type: string
enum:
- active
- inactive
- pending
src/schemas.ts contains one Zod schema and one TypeScript type per schema in the specification:
// Auto-generated by @spartaficial/openapi-to-zod
// API: Simple Test API
// Version: 1.0.0
// Do not edit this file manually
// Generation Statistics:
// Total schemas: 2
// Circular references: 0
// Discriminated unions: 0
// With constraints: 0
import { z } from "zod";
// Schemas and Types
/** A user in the system */
export const userSchema = z.strictObject({
/** The unique identifier for the user */
id: z.uuid(),
/** The user's full name */
name: z.string(),
/** The user's email address */
email: z.email().optional(),
/** The user's age in years */
age: z.number().int().optional(),
});
export type User = z.infer<typeof userSchema>;
export const statusSchema = z.enum(["active", "inactive", "pending"]);
export type Status = z.infer<typeof statusSchema>;
Three things in this file come from the configuration. mode: 'strict' is why the object is a z.strictObject: a response carrying a property the specification does not describe fails validation instead of passing unnoticed, which is usually what you want from a schema whose job is to catch drift between an API and its documentation. includeDescriptions: true turned the description fields into JSDoc comments. showStats: true added the statistics block to the header.
Use the schema wherever data crosses a boundary you do not control:
import { userSchema, type User } from "./src/schemas";
const body: unknown = await response.json();
const user: User = userSchema.parse(body); // throws a ZodError when the body does not match
User is inferred from the schema, so the type and the validation can never disagree. The generated file depends only on zod; it has no dependency on the generator and no licence logic, so it can be committed and built like any other source file. Regenerate whenever the specification changes.
Set your licence key
Generation reads your licence from the environment variable SPARTAFICIAL_LICENSE_KEY; set it in your shell and as a secret in CI, and see licensing.md for what a key covers, what runs without one, and what each error code means.
Where to go next
Concepts, which apply to every generator:
- concepts/configuration-files.md: discovery, TypeScript versus JSON,
defaultsandspecs,executionMode, validation errors. - concepts/specs-and-references.md: input formats, specifications split across files,
refMappings, warnings. - concepts/operation-filters.md: choosing which operations, and in the Playwright generator which responses, to generate.
- concepts/naming.md: how schema and operation names become identifiers, and the options that shape them.
- concepts/request-and-response-shapes.md:
readOnly,writeOnlyandschemaType. - concepts/runtime-entry-points.md: the
/runtimemodules the k6 and Playwright output imports.
One page per generator:
Reference:
- reference/cli.md: every command and flag.
- reference/options-typescript.md, reference/options-zod.md, reference/options-zod-playwright.md, reference/options-k6.md: every option of each generator, and reference/option-parity.md for which option exists where.
- reference/openapi-core.md: the shared library, for writing your own generator.
- reference/openapi-feature-support.md: which OpenAPI constructs each generator handles.
And the rest: