Skip to content

04Reference

Compatibility

Specification features, runtimes and dependency versions that are verified.

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).

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.

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.

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.

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).

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.