OpenAPI Qraft CLI
OpenAPI Qraft CLI is a command-line utility that generates API schemas and interfaces for the @openapi-qraft/react.
With the @openapi-qraft/cli and @openapi-qraft/react packages, you can build a type-safe API client with React Hooks
based on the OpenAPI Document.
Qraft relies on types from the generation result of openapi-typescript package,
which is a powerful tool for generating types from an OpenAPI schema.
If you missed the installation step, you can install the @openapi-qraft/cli using the following command:
- npm
- yarn
- pnpm
npm install -D @openapi-qraft/cli
yarn add --dev @openapi-qraft/cli
pnpm add -D @openapi-qraft/cli
Usageโ
The command below generates Qraft API services for the OpenAPI schema and places them in the src/api directory:
- npm
- yarn
- pnpm
npx openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml \
--output-dir src/api
yarn exec openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml \
--output-dir src/api
pnpm exec openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml \
--output-dir src/api
Optionsโ
Requiredโ
-o <path>, --output-dir <path>: Specify where to output the generated services.- Example:
--output-dir src/api
- Example:
Edge-case Optionsโ
-
-c, --clean: Clean the specified output directory services before generating to remove stale files (optional). -
--filter-services <glob-patterns...>: Filter services to be generated by glob pattern (optional).- Pattern syntax:
<glob-pattern>,<glob-pattern>,...- comma-separated list of glob patterns. Seemicromatchpackage for more details. More than one pattern can be specified.
- Examples:
--filter-services '/user/**,/post/**'- include only API endpoints that start with/user/or/post/--filter-services '**,!/internal/**'- include all API endpoints except those that start with/internal/
- Pattern syntax:
-
--operation-predefined-parameters <patterns...>: Predefined parameters for services. The specified services parameters will be optional. (optional)- Pattern syntax:
<path glob>:<operation parameter>,...<method> <path glob>:<operation parameter>,...- Each modifier consists of an optional method, a path glob pattern, a colon, and a comma-separated list of operation parameters to be set as optional. More than one predefined parameter option can be specified.
This option ๐ is arguably one of the most awesome features, allowing you to set default parameters across multiple endpoints. However, if an endpoint doesn't contain a parameter specified in this option, an error will be displayed. For example:
โ Missing predefined parameter 'header' 'x-monite-version' in 'post /files' in '/**'To resolve such errors, you can exclude specific endpoints from the predefined parameters using the negation syntax in the glob pattern, like:
--operation-predefined-parameters '/**,!/files:header.x-monite-version'- Examples:
--operation-predefined-parameters '/**:header.x-monite-version'- setheader.x-monite-versionas optional parameters for all services.--operation-predefined-parameters '/**,!/auth/token:header.x-entity-id'- setheader.x-entity-idas optional parameters for all services except/auth/token.--operation-predefined-parameters 'post,put /**:header.x-entity-id'- set theHeaderrecordx-entity-idas an optional parameter for thePOSTandPUTmethods.
- Pattern syntax:
-
--operation-name-modifier <patterns...>: Modifies operation names using a pattern.- Pattern syntax:
<path glob>:<regular expression> ==> <new operation name><method> <path glob>:<regular expression> ==> <new operation name>- Each modifier consists of an optional method, a path glob pattern,
a colon, and a regular expression that matches the operation name. The part after
==>is the new operation name. More than one modifier option can be specified.
- Examples:
--operation-name-modifier 'get /**:[A-Za-z]+Id ==> findOne'- will change allGEToperations withIdsuffix tofindOne.--operation-name-modifier 'get /**:get(.*) ==> find-$1'- will change allGEToperations withgetprefix tofindById | findAll | ....- The pattern is a regular expression that matches the operation name.
- The operation name is converted to Camel Case. Spaces, hyphens, and underscores are removed.
--operation-name-modifier 'put,patch /**:[A-Za-z]+Id ==> updateOne'- will change allPUTandPATCHoperations withIdsuffix toupdateOne.--operation-name-modifier '/posts,/files:create[a-zA-Z]+ ==> createOne'- will change all operations under/postsand/filestocreateOneif the operation name starts withcreate.--operation-name-modifier 'post /files ==> createOne' 'put /posts ==> updateOne'- will change allPOSToperations under/filestocreateOneand allPUToperations under/poststoupdateOne.
- Pattern syntax:
-
--explicit-component-exports: Enabling this option will export API components as separate type aliases, alongsidecomponentsinterface. -
--redocly [config]: Use the Redocly configuration to generate multiple API clients. If the[config]parameter is not specified, the default Redocly configuration will be used:[redocly.yaml | redocly.yml | .redocly.yaml | .redocly.yml]. (optional)- Examples:
--redocly- use the default Redocly configuration file--redocly ./my-redocly-config.yaml- use a custom Redocly configuration fileopenapi-qraft my-api@v1 external-api --redocly- generate clients for multiple APIs defined in the Redocly configuration
- For more information about this option, use the command:
--redocly-helpor read the docs.
- Examples:
-
--service-name-base <endpoint[<index>] | tags>: Use OpenAPI Operationendpoint[<index>]path part (e.g.:/0/1/2) ortagsas the base name of the service. (optional, default:endpoint[0]).endpoint[<index>]- Use the path segment (e.g.,/0/1/2) as the base name for the service.- Examples:
--service-name-base endpoint[0]generatesservices/FooService.tsfor the endpoint/foo/bar/baz--service-name-base endpoint[1]generatesservices/BarService.tsfor the endpoint/foo/bar/baz--service-name-base endpoint[3]generatesservices/BazService.tsfor the endpoint/foo/bar/baz(if the endpoint is shorter than the index, the last part is used)- If used
endpoint[<index>]as the base name, operation names will be generated according to the specified index.- For example:
--service-name-base endpoint[1]for the endpoint/api/bargeneratesgetoperation name.--service-name-base endpoint[1]for the endpoint/api/foo/bargeneratesgetBaroperation name.
- For example:
- Examples:
tags- Use the OpenAPI Operationtagsas the base name of the service.- Examples:
--service-name-base tagswill generate services based on the OpenAPI Operation tags instead of the endpoint.- If multiple tags are present for the operation, similar services will be created for each tag. Operation with
tags: [Foo, Bar]will generateservices/FooService.tsandservices/BarService.ts. - If there are no tags for the operation, the services will be created under the
defaulttag. Operation with emptytags: []will generateservices/DefaultService.ts. - If
tagsare used as the base name, operation names will be generated based on theoperationIdfrom the OpenAPI Operation, or from the path ifoperationIdis not provided. You can use--operation-name-modifierto customize the operation names.
- If multiple tags are present for the operation, similar services will be created for each tag. Operation with
- Examples:
-
--explicit-import-extensions [extension]: All import statements will contain an explicit file extension. Ideal for projects using ECMAScript modules when TypeScript's --moduleResolution isnode16ornodenext. Choices:.js,.ts, preset:.js. (optional) -
--file-header <string>: Add a custom header to each generated file, useful for disabling linting rules or adding file comments (optional).- Example:
--file-header '/* eslint-disable */'
- Example:
-
--postfix-services <string>: Customize the generated service names with a specific postfix (optional, default:Service).- Example:
--postfix-services Endpointwill generateservices/UserEndpoint.tsinstead ofservices/UserService.ts.
- Example:
-
--plugin <name_1> --plugin <name_2>: Generator plugins to be used. (choices:tanstack-query-react,openapi-typescript)- Examples:
--plugin tanstack-query-react --plugin openapi-typescriptgenerates Qraft Services andopenapi-typescripttypes file.--plugin tanstack-query-reactgenerates Qraft Services only.--plugin openapi-typescriptgeneratesopenapi-typescripttypes file only.
- Examples:
-
-h, --help: Display help for the command (optional).
Plugin Systemโ
The following plugins are currently supported:
openapi-typescript- Generates TypeScript types from an OpenAPI Document. The main difference from the originalopenapi-typescriptpackage is thatformat: binaryfields default toBlobtypes instead of remaining asstring. This behavior can be altered using the--no-blob-from-binaryoption.tanstack-query-react- Generates Qraft API services for React.
Plugin must be provided with the --plugin <name> option. By default, the tanstack-query-react plugin is used.
It is possible to use multiple plugins at the same time. For example, --plugin tanstack-query-react --plugin openapi-typescript generates Qraft API services & schema types file.
--plugin tanstack-query-react optionsโ
-
--openapi-types-import-path <path>: Set the path to the schema types definition file to ensure consistent type usage (assumed, you already haveschema.d.tsas a result of theopenapi-typescriptutility). You also probably don't need theoption in this case.--plugin openapi-typescript- The path is the exact import specifier used in the generated services. It should be relative to the service
output directory. Optional, if the
--plugin openapi-typescriptis used. Required otherwise.- Examples:
--openapi-types-import-path ../openapi.d.ts--openapi-types-import-path '@/api/openapi.d.ts'--openapi-types-import-path '@external-package-types'
- Examples:
- The path is the exact import specifier used in the generated services. It should be relative to the service
output directory. Optional, if the
-
--export-openapi-types [bool]: Add an export statement of the generated OpenAPI document types from the./index.tsfile. Useful for sharing types within your project. (optional, default:true, if--plugin openapi-typescriptis used) -
--override-import-type <pathname overrides...>: Override import paths for specific types in generated files. This allows using custom type implementations instead of the default ones. The option expects a filepath followed by one or more type override definitions in formatoriginalModule:importTypeName:customImportPath. Can be specified multiple times to define different overrides. (optional)- Examples:
--override-import-type services @openapi-qraft/tanstack-query-react-types:OperationError:../../type-overrides/operation-error.js- replaces the import ofOperationErrortype from@openapi-qraft/tanstack-query-react-typeswith an import from../../type-overrides/operation-error.jsin all service files.--override-import-type create-api-client @openapi-qraft/react:CreateAPIQueryClientOptions:../type-overrides/create-query-client-options.js- replaces the import in thecreate-api-client.tsfile.
- This option is particularly useful when you need to provide custom implementations of library types that better suit your project's needs.
- Examples:
-
--operation-parameters-type-wrapper <parameters wrappers...>: Configure custom ParametersWrapper types for specific operation patterns. This allows you to use custom type implementations for operation parameters instead of the default generated types. The option expects a pattern followed bytype:TypeNameandimport:ImportPath. Can be specified multiple times for different patterns. (optional)- Format:
<pattern> type:<TypeName> import:<ImportPath> - The
ParametersWrappertype receives four generic parameters:TSchema- The operation schema (method, url)TOperation- The operation type from OpenAPI pathsTData- The response data typeTError- The error type
- Note: Generic parameters
TSchema,TData, andTErrormay appear unused in the type body, but they are required for proper type inference and are passed by the code generator. If your linter flags them as unused, you can disable the rule for your type definition file using/* eslint-disable @typescript-eslint/no-unused-vars */or configure ESLint to ignore this specific file. - Pattern syntax:
<method> <path glob>- Match operations by HTTP method and path pattern<path glob>- Match operations by path pattern only (all methods)- Supports glob patterns (wildcards) for flexible matching
- Negative patterns: Use
!prefix to exclude specific paths (e.g.,'/*,!/fields'means all paths except/fields)
- Examples:
--operation-parameters-type-wrapper 'get /files/**' 'type:ReadParametersWrapper' 'import:../../type-overrides/parameters-wrapper.js'- Use ParametersWrapper for all GET operations under/files/**--operation-parameters-type-wrapper 'delete /approval_policies/{approval_policy_id}' 'type:DeleteParametersWrapper' 'import:../../type-overrides/parameters-wrapper.js'- Use ParametersWrapper for a specific DELETE operation--operation-parameters-type-wrapper 'post,put /api/**' 'type:WriteParametersWrapper' 'import:../types/write-parameters-wrapper.js'- Use WriteParametersWrapper for POST and PUT operations under/api/**--operation-parameters-type-wrapper '/**,!/fields' 'type:ItemsQueryParametersWrapper' 'import:./types'- Use ItemsQueryParametersWrapper for all paths except/fields
- This option is particularly useful when you need to provide custom parameter handling logic or transform parameters before they are used in API calls.
- Format:
-
--create-api-client-fn <functionName> [options...]: Configure API client creation function. Allows specifying the function name used to create the API client, as well as fine-tuning included services and callbacks. You can specify this option multiple times to generate several different API client creation functions from a single OpenAPI document - for example, a fully-featured client for Node.js and a lightweight client for React or service workers. (optional) See examples on theuseQuery()documentation page.- Options:
filename:<name>- filename where the function will be generated (defaults to function name)services:[all|none]- Specify whether the generated API client should include services: either all available services, or no services by default.all- include all available servicesnone- don't include any services by default (they must be specified when calling the function)
callbacks:[all|none|callback1,callback2,...]- list of callbacks to be included in the API client by defaultall- include all available callbacks (useQuery, useMutation, setQueryData, etc.)none- don't include any callbacks by default (they must be specified when calling the function)useQuery,useMutation,...- list of specific callbacks to include
- Examples:
--create-api-client-fn createAPIClient services:all callbacks:all- creates thecreateAPIClient()function that includes all services and all callbacks by default (default behavior)--create-api-client-fn createMinimalAPIClient services:none callbacks:none- creates thecreateMinimalAPIClient()function that generates a super lightweight ๐ชถ API client with zero overhead - no default services or callbacks included. Perfect for building a minimal bundle size client where you explicitly control which services and callbacks to include.--create-api-client-fn createCustomClient filename:create-custom-api services:none callbacks:setQueryData,getQueryData- creates thecreateCustomClient()function in thecreate-custom-api.tsfile with no default services and onlysetQueryData()andgetQueryData()callbacks
tipWhen generating multiple API client functions with different parameters, it might be more convenient to use a configuration file instead of command-line parameters. See the Redocly configuration documentation for more details on how to configure multiple create API client functions in a YAML file.
- Options:
--plugin openapi-typescript optionsโ
--queryable-write-operations [bool]: Enable generation of query hooks (useQuery,useSuspenseQuery, etc.) for writable HTTP methods like POST, PUT, PATCH. By default, only mutation hooks are generated for writable operations.--openapi-types-file-name <path>: OpenAPI Schema types file name, e.g.,schema.d.ts(default:schema.ts).--enum: Export true TypeScript enums instead of unions.--enum-values: Export enum values as arrays.--dedupe-enums: Dedupe enum types when--enumis set.-t, --export-type: Export top-leveltypeinstead ofinterface.--immutable: Generate readonly types.--additional-properties: Treat schema objects as ifadditionalProperties: trueis set.--empty-objects-unknown: Generateunknowninstead ofRecord<string, never>for empty objects.--default-non-nullable: Set tofalseto ignore default values when generating non-nullable types.--properties-required-by-default: Treat schema objects as ifrequiredis set to all properties by default.--array-length: Generate tuples using arrayminItems/maxItems.--path-params-as-types: Convert paths to template literal types.--alphabetize: Sort object keys alphabetically.--exclude-deprecated: Exclude deprecated types.--no-blob-from-binary: If this option is enabled,format: binaryfields will not be converted toBlobtypes, preserving the native type. Could be used with--plugin openapi-typescriptoption.--explicit-component-exports: Enabling this option will export API components as separate type aliases, alongsidecomponentsinterface.
In-project Setupโ
Add the following "scripts" to your package.json file:
{
"devDependencies": {
"@openapi-qraft/cli": "latest"
},
"scripts": {
"generate-client": "openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml --output-dir src/api",
// ...other scripts
}
}