Skip to content

02Guides

JavaScript output

Plain ES modules with JSDoc types and declaration files.

output.language: 'javascript' emits the same client as plain ES modules: no TypeScript syntax, types expressed as JSDoc, and .d.ts declarations next to every module. Projects without a TypeScript build get the same autocomplete and the same runtime behavior.

export default defineConfig({
spec: { version: '3.0', input: './openapi.yaml' },
output: { language: 'javascript' },
});
/**
* Parameters of {@link getPetById}.
*
* @typedef {object} GetPetByIdParams
* @property {number} petId - ID of pet to return
*/
/**
* Find pet by ID.
*
* @param {GetPetByIdParams} params - Request parameters.
* @param {import('../client.js').RequestOptions} [options] - Per-request options: `signal`, `timeout`, `headers`, `client`.
* @returns {Promise<GetPetByIdResponse>} `200` successful operation
*/
export function getPetById(params, options) {
/* … */
}

Every module is rendered three times from the same code paths: TypeScript, JavaScript with JSDoc, and declarations. That is why both languages behave identically: there is no separate JavaScript generator to fall behind.

  • Types become @typedefs; parameters and return values are annotated with @param and @returns.
  • Type imports are written as import('…') types, so .js files contain no TypeScript syntax at all.
  • .d.ts files are emitted next to every module unless output.declarations: false; the runtime always has declarations.
  • The test suite type-checks JavaScript output with checkJs and strict settings, with and without declarations, and checks that the .js files contain no TypeScript syntax.

The output is ES modules. In Node.js the package that imports it needs "type": "module" (or a bundler). The node-javascript example is a plain Node.js project that uses the JavaScript client with API-key auth, middleware and typed errors.

  • The output targets ES2020; older runtimes need a bundler that transpiles it.
  • Only ES modules are generated (output.moduleFormat is reserved for later).

What's generated

petstore.yaml
openapi: 3.1.0
info:
title: Petstore
version: '1.0'
servers:
- url: https://petstore.example.com/v1
paths:
/pets/{petId}:
get:
tags: [pets]
summary: Find a pet by ID.
description: Returns a single pet.
operationId: getPetById
parameters:
- name: petId
in: path
required: true
description: ID of the pet to return.
schema:
type: integer
format: int64
minimum: 1
responses:
'200':
description: The pet.
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
'404':
description: No pet has this ID.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
security:
- api_key: []
components:
securitySchemes:
api_key:
type: apiKey
in: header
name: X-API-Key
schemas:
Pet:
type: object
required: [id, name]
properties:
id:
type: integer
format: int64
name:
type: string
example: Rex
status:
type: string
description: Where the pet is in the store.
enum: [available, pending, sold]
Error:
type: object
required: [message]
properties:
message:
type: string

pets/get-pet-by-id.js

/* eslint-disable */
// @generated by swaggerz. Do not edit: this file is overwritten on the next generation.
import { client } from '../client.js';
import { isApiError } from '../runtime/errors.js';
/**
* Parameters of {@link getPetById}.
*
* @typedef {object} GetPetByIdParams
* @property {number} petId - ID of the pet to return.
*/
/**
* Response data of {@link getPetById}.
*
* @typedef {import('../models/pet.js').Pet} GetPetByIdResponse
*/
/**
* Body of an error response of {@link getPetById}.
*
* @typedef {import('../models/error.js').Error} GetPetByIdErrorBody
*/
/**
* The `ApiError`s {@link getPetById} rejects with: one per documented status, so checking `status` narrows `body`.
*
* The last member covers statuses the specification does not document.
*
* @typedef {import('../runtime/errors.js').ApiError<import('../models/error.js').Error, 404> | import('../runtime/errors.js').ApiError<unknown, Exclude<import('../runtime/types.js').HttpStatus<1 | 3 | 4 | 5>, 404>>} GetPetByIdApiError
*/
/**
* Everything {@link getPetById} rejects with: an `ApiError` for an error status, or a `RequestError` when no usable response arrived.
*
* @typedef {GetPetByIdApiError | import('../runtime/errors.js').RequestError} GetPetByIdError
*/
/**
* Find a pet by ID.
*
* Returns a single pet.
*
* @remarks `GET /pets/{petId}` (operationId `getPetById`)
* @param {GetPetByIdParams} params - Request parameters.
* @param {import('../client.js').RequestOptions} [options] - Per-request options: `signal`, `timeout`, `headers`, `client`.
* @returns {Promise<GetPetByIdResponse>} `200` The pet
* @throws {import('../runtime/errors.js').ApiError} `404` No pet has this ID; narrow it with {@link isGetPetByIdApiError}.
* @throws {import('../runtime/errors.js').RequestError} When no usable response is received (network failure, timeout or invalid body).
*/
export function getPetById(params, options) {
return (options?.client ?? client).request(
{
operationId: 'getPetById',
method: 'GET',
path: '/pets/{petId}',
pathParams: { petId: params.petId },
accept: 'application/json',
security: [['api_key']],
},
options,
);
}
/**
* Whether `error` is an `ApiError` rejected by {@link getPetById}. It narrows to {@link GetPetByIdApiError}, so checking `status` afterwards narrows `body` too.
*
* @param {unknown} error
* @returns {error is GetPetByIdApiError}
*/
export function isGetPetByIdApiError(error) {
return (
isApiError(error) &&
error.operationId === 'getPetById' &&
error.method === 'GET'
);
}

pets/get-pet-by-id.d.ts

/* eslint-disable */
// @generated by swaggerz. Do not edit: this file is overwritten on the next generation.
import type { RequestOptions } from '../client.js';
import type { Error as ErrorModel } from '../models/error.js';
import type { Pet } from '../models/pet.js';
import type { ApiError, RequestError } from '../runtime/errors.js';
import type { HttpStatus } from '../runtime/types.js';
/** Parameters of {@link getPetById}. */
export type GetPetByIdParams = {
/**
* ID of the pet to return.
*
* @format int64
* @minimum 1
*/
petId: number;
};
/** Response data of {@link getPetById}. */
export type GetPetByIdResponse = Pet;
/** Body of an error response of {@link getPetById}. */
export type GetPetByIdErrorBody = ErrorModel;
/**
* The `ApiError`s {@link getPetById} rejects with: one per documented status, so checking `status` narrows `body`.
*
* The last member covers statuses the specification does not document.
*/
export type GetPetByIdApiError =
| ApiError<ErrorModel, 404>
| ApiError<unknown, Exclude<HttpStatus<1 | 3 | 4 | 5>, 404>>;
/** Everything {@link getPetById} rejects with: an `ApiError` for an error status, or a `RequestError` when no usable response arrived. */
export type GetPetByIdError = GetPetByIdApiError | RequestError;
/**
* Find a pet by ID.
*
* Returns a single pet.
*
* @remarks `GET /pets/{petId}` (operationId `getPetById`)
* @param params - Request parameters.
* @param options - Per-request options: `signal`, `timeout`, `headers`, `client`.
* @returns `200` The pet
* @throws {@link ApiError} `404` No pet has this ID; narrow it with {@link isGetPetByIdApiError}.
* @throws {@link RequestError} When no usable response is received (network failure, timeout or invalid body).
*/
export declare function getPetById(params: GetPetByIdParams, options?: RequestOptions): Promise<GetPetByIdResponse>;
/** Whether `error` is an `ApiError` rejected by {@link getPetById}. It narrows to {@link GetPetByIdApiError}, so checking `status` afterwards narrows `body` too. */
export declare function isGetPetByIdApiError(error: unknown): error is GetPetByIdApiError;
Generated by swaggerz 0.1.2 with { output: { language: 'javascript' } }, at build time.