04Reference
Compatibility
Specification features, runtimes and dependency versions that are verified.
Runtime environments of generated code
Section titled “Runtime environments of generated code”Generated clients target ES2020 and only use standard APIs: fetch, Headers, AbortController, FormData, Blob, URLSearchParams, TextEncoder and btoa (or axios). pnpm test:runtimes (scripts/runtimes.ts) runs the same suite of checks (tests/runtimes/suite.js: JSON, query and path serialization, JSON and multipart bodies, binary responses, API keys, typed errors and their guards, timeouts, cancellation, middleware, retry() and refreshAuth()) against a local server in every runtime below, then the mock checks (tests/runtimes/mocks-suite.js: fixtures, documented statuses, response functions reading parameters, JSON and multipart bodies, network errors) through the generated mockFetch(); CI runs each one in its own job:
| Runtime | Client | How |
|---|---|---|
| Node.js 18, 20, 22, 24 | JavaScript; TypeScript (.ts imports) on 24 |
tests/smoke/runtime.mjs on each version |
| Deno 2 | JavaScript and TypeScript (.ts imports) |
deno run |
| Bun 1.3 | JavaScript and TypeScript (.ts imports) |
bun |
| Chromium, Firefox, WebKit (Safari) | JavaScript, loaded as native ES modules | Playwright |
| workerd (Cloudflare Workers) | JavaScript, bundled into a module worker | miniflare |
The runtimes come from PATH or are installed into .runtimes/ on demand; the project does not depend on them. MSW needs --allow-env in Deno and the nodejs_compat compatibility flag in workerd. pnpm examples:browsers runs the React Query, Vue Query, Svelte Query, Solid Query and SWR examples on their generated MSW service worker in Chromium, Firefox and WebKit. The integration tests also run clients in Node.js and in happy-dom (React Query and SWR hooks; the mock handlers with the fetch and axios adapters), and the Vue Query composables in Node.js with Vue’s reactivity. Other edge runtimes (Vercel, Netlify, Deno Deploy) implement the same web APIs but are not run. Generated modules are ES modules: in Node.js the consuming package needs "type": "module" (or a bundler). The runtime is type-checked against both a browser environment (lib: ES2020 + DOM, no Node types) and a Node.js environment (@types/node, no DOM, NodeNext resolution).
Tested versions
Section titled “Tested versions”pnpm compat installs the oldest supported versions side by side and type-checks generated clients (TypeScript output, JavaScript declarations, the hooks of every data-fetching library, the schemas of every validation library, the mock handlers) with TypeScript 5.0, 6 and 7; the newest versions are the repository’s own dependencies, used by the integration tests. Both use the strictest settings (strict, exactOptionalPropertyTypes, noUncheckedIndexedAccess, noPropertyAccessFromIndexSignature, noUnused*, verbatimModuleSyntax, isolatedModules):
| Dependency | Oldest verified | Newest verified |
|---|---|---|
| TypeScript | 5.0.4 (5.4.5 with ArkType) | 6.0.3 and 7.0 (native compiler) |
@tanstack/react-query |
5.0.0 | 5.104 |
@tanstack/vue-query |
5.0.0 (Vue 3.3.4) | 5.104 (Vue 3.5) |
@tanstack/svelte-query |
6.0.0 (Svelte 5.25) | 6.3 (Svelte 5.57) |
@tanstack/solid-query |
5.0.0 (Solid 1.8) | 5.104 (Solid 1.9) |
| SWR | 2.2.0 | 2.5 |
| axios | 1.0.0 | 1.20 |
| Zod | 4.0.15 | 4.6 |
| Valibot | 1.0.0 | 1.5 |
| ArkType | 2.0.0 | 2.2.9 |
| MSW | 2.11.0 | 3.0 |
| Node.js (generator) | 22.18.0 | 24 |
The generator’s own test suite and the packed-tarball check (pnpm test:pack) pass on Node.js 22.18.0 and 24, on macOS and on Linux (verified in a Debian container on arm64, including file watching, generate --watch and the dashboard’s live reload). The CI matrix also runs the suite on Windows; the code paths that differ there (paths, case-insensitive file names, signals, .cmd launchers) were reviewed, and Windows is verified once that CI job has run. erasableSyntaxOnly, available from TypeScript 5.8, is enabled for the newer compilers to prove the output contains no enums or namespaces.
ArkType’s own types do not type-check with TypeScript 5.3 or older, so ArkType output is verified from TypeScript 5.4; swaggerz doctor requires 5.4 when ArkType is configured. SWR changed the order of its mutation types’ generics in 2.2, which is therefore its minimum; Svelte Query 6 is the Svelte 5 (runes) adapter, so Svelte Query 5 (Svelte 3 and 4 stores) is not supported.
MSW 2.11 added the custom request predicates the generated mock handlers match with, so it is the minimum; swaggerz doctor checks it when mocks are enabled. MSW 3 renamed the onUnhandledRequest option of setupServer().listen() and setupWorker().start() to onUnhandledFrame; the generated handlers work with both.
Zod 4.0.0 – 4.0.14 cannot infer recursive schemas defined with getters (the pattern Zod 4 recommends and swaggerz generates) under TypeScript 6 and 7: the compiler reports TS2615 (“circularly references itself in mapped type”). Zod 4.0.15 fixed this, so it is the minimum version; swaggerz doctor checks it when validation is enabled.
Specification support
Section titled “Specification support”| Feature | 2.0 | 3.0 | 3.1 | 3.2 | Notes |
|---|---|---|---|---|---|
| JSON and YAML, local and remote | ✓ | ✓ | ✓ | ✓ | YAML 1.2 core schema, duplicate keys rejected, alias expansion bounded |
Internal, external and recursive $ref |
✓ | ✓ | ✓ | ✓ | Reference policy; cycles of pure references are errors |
$ref siblings |
ignored (warning) | ignored (warning) | ✓ | ✓ | |
$anchor, $id |
– | – | ✓ | ✓ (+ $self) |
Nested and relative $id base URIs (JSON Schema 2020-12); ids known in the document are never fetched |
| Path, query, header, cookie parameters | ✓ | ✓ | ✓ | ✓ (+ querystring) |
Accept, Content-Type, Authorization header parameters ignored in 3.x, as the spec requires |
style / explode / allowReserved / content parameters |
collectionFormat |
✓ | ✓ | ✓ (+ cookie) |
tsv maps to tab-delimited |
| Request bodies, multiple media types | body, formData |
✓ | ✓ | ✓ | Every media type is typed; a contentType parameter selects one (JSON preferred by default) |
| Multipart and file uploads | ✓ | ✓ | ✓ | ✓ | encoding for property content types and array serialization |
| Binary responses | ✓ | ✓ | ✓ | ✓ | Blob |
Multiple responses and ranges (2XX, default) |
✓ | ✓ | ✓ | ✓ | Declared 3XX responses (304) resolve instead of rejecting |
allOf / oneOf / anyOf |
allOf (+ others with warning) |
✓ | ✓ | ✓ | |
| Discriminators | ✓ (property name) | ✓ (mapping) | ✓ | ✓ (+ defaultMapping) |
Implicit and explicit mappings, allOf inheritance |
| Nullability | x-nullable |
nullable |
type arrays, oneOf with null |
type arrays, oneOf with null |
nullable in 3.1 is ignored with a warning |
readOnly / writeOnly |
readOnly |
✓ | ✓ | ✓ | Split into response and …Input request types (types.readWrite) |
format: date, date-time |
✓ | ✓ | ✓ | ✓ | string, or Date with runtime conversion (types.dates) |
Operation and path servers |
– | ✓ | ✓ | ✓ | Used per operation (client.operationServers) |
const, prefixItems, boolean schemas |
– | const (warning) |
✓ | ✓ | |
not, if/then/else, dependentSchemas, dependentRequired |
not |
not |
✓ | ✓ | Enforced by the generated schemas (schema/assertion-keyword); TypeScript types stay wider |
$dynamicRef, $recursiveRef |
– | – | ignored (warning) | ignored (warning) | Types may be wider than the schema |
| Security schemes | basic, apiKey, oauth2 | ✓ | ✓ (+ mutualTLS ignored) | ✓ (+ device flow) | |
| Webhooks, callbacks | – | callbacks | ✓ | ✓ | Payload, response and handler types (output.webhooks) |
| Vendor extensions | preserved | preserved | preserved | preserved | Available to plugins; x-enum-varnames/x-enumNames, x-discriminator-value, x-deprecated, x-example are used |
QUERY method, additionalOperations |
– | – | – | ✓ | Other methods are sent exactly as their key is spelled (COPY); QUERY operations are React Query queries by default |
in: querystring parameters |
– | – | – | ✓ | One typed object for the whole query string: form-urlencoded (with encoding), JSON or text, percent-encoded |
style: cookie |
– | – | – | ✓ | ; -separated cookies, no percent-encoding |
Sequential media types with itemSchema |
– | – | – | as text | JSON Lines, NDJSON, JSON sequences and SSE responses are typed and read as text (operation/item-schema); the item models are generated. Streaming iterators are not generated yet |
itemEncoding, prefixEncoding |
– | – | – | ignored | Positional multipart encoding is not used |
Tag parent, kind, summary |
– | – | – | ✓ | Nested tags become nested directories (groupBy: 'tag'), nested React Query keys and a tag tree in the dashboard; undeclared or circular parents are dropped (spec/invalid-tag-parent) |
$self |
– | – | – | ✓ | Base URI and identity of a document; references next to it are read next to the referencing file |
components.mediaTypes, media type $ref |
– | – | – | ✓ | |
| Security requirements by URI | – | – | – | ✓ | Only schemes in the entry document’s components.securitySchemes |
OAuth 2 device flow, oauth2MetadataUrl, deprecated schemes |
– | – | – | ✓ | Kept in the IR and shown in the dashboard; tokens are sent as Bearer |
Example dataValue / serializedValue |
– | – | – | ✓ | dataValue is used like value |
Response summary, server name |
– | – | – | ✓ | Shown in documentation comments and the dashboard |
xml.nodeType |
– | – | – | ignored | XML bodies are passed as strings in every version |
swaggerz validates what code generation depends on (required fields, parameter shape, references, types) and reports problems with locations; it is not a complete specification linter. Use a dedicated linter such as Spectral or Redocly for style and full conformance checks.
Usage scanning (dashboard)
Section titled “Usage scanning (dashboard)”The dashboard’s usage view parses your sources with oxc-parser and resolves imports with oxc-resolver (honoring tsconfig.json paths). Both are optional dependencies of swaggerz with prebuilt binaries for the common platforms; no TypeScript installation is needed. If they are unavailable (installed with --omit=optional, or an unsupported platform), the usage view says so and everything else works.
Fixtures
Section titled “Fixtures”The test fixtures cover each family: petstore-2.0.json, petstore-3.0.yaml, features-3.1.yaml (composition, discriminators, recursion, tuples, styles), features-3.2.yaml (every OpenAPI 3.2 addition above, with features-3.2-shared.yaml for $self), real-world/ (patterns from public descriptions that once produced invalid code), a multi-file specification with recursive cross-file references, edge cases for naming and escaping, advanced-3.1.yaml (read/write split, dates, multiple media types, 304, operation servers, webhooks, callbacks, assertions), ids-3.1.yaml (nested relative $id scopes), mocks-3.1.yaml (mock handlers: route matching, statuses, media types, examples and constraints), and invalid documents (broken and circular references, blocked references, malformed YAML, non-OpenAPI input).
Public API corpus
Section titled “Public API corpus”pnpm corpus (scripts/corpus.ts, run in CI) compiles 24 public API descriptions (Kubernetes, Slack, Stripe, GitHub (OpenAPI 3.0 and 3.1), Twilio, Box, Asana, Plaid, Spotify, DigitalOcean (about 1,900 files), OpenAI, Discord, Train Travel (3.2), and the OpenAPI Initiative’s examples for 3.0, 3.1 and 3.2) with React Query, Zod, Date conversion and mocks enabled, type-checks every generated client with the strictest settings, and compares the outcome with fixtures/corpus/baseline.json. Each document is pinned to a commit and a checksum (fixtures/corpus/corpus.json), so a crash, a type error in generated code or any change in the reported diagnostics fails the job; --update records intended changes. Together they are about 6,900 operations and 11,600 models.