Library / SDK
openapistack/openapi-client-axios avatar
openapistack/openapi-client-axios

openapi-client-axios: a runtime OpenAPI client with no generated code

JavaScript client library for consuming OpenAPI-enabled APIs with axios

617 stars69 forksTypeScriptMIT

At a glance

What is it?
openapi-client-axios turns an OpenAPI v3 definition into a live axios instance at runtime, so the operation methods exist at call time rather than being compiled into your bundle, and the TypeScript types come from a separate typegen command. It is MIT licensed and is the client the OpenAPI Stack project builds its other tools around.
Who is it for?
openapi-client-axios suits a browser or Node application that consumes several OpenAPI-described services and wants one client shape across all of them without a build step, and it suits a team that wants the OpenAPI definition to stay the single source of truth.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 14 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The client is built at runtime from the definition

openapi-client-axios is a JavaScript client library for consuming OpenAPI enabled APIs with axios, types included. The feature list leads with the point that distinguishes it from the code generation approach.

It creates API clients from OpenAPI v3 definitions, and the client is configured in runtime with no generated code. The other features follow from that: it generates TypeScript definitions for your APIs with full IntelliSense support, it offers an easy API to call API operations using JavaScript methods, it is built on top of the axios library, and it is isomorphic, working both in browser and in Node.js.

The runtime approach has a clear trade. A generated client is typed from the moment you build, but you have to regenerate and recompile whenever the API changes, and a generated bundle is a large artefact to keep in version control. A runtime client fetches the definition when the application starts, so the definition is always current, but the method calls are only typed if you also run the type generation step and keep the result in your repository.

That split is visible in the quick start. The dependency install is a plain npm or yarn command:

code
npm install --save axios openapi-client-axios
code
yarn add axios openapi-client-axios

And then the client is constructed from a definition URL, with a promise chain in the CommonJS form:

javascript
const OpenAPIClientAxios = require('openapi-client-axios').default;

const api = new OpenAPIClientAxios({ definition: 'https://example.com/api/openapi.json' });
api.init()
  .then(client => client.getPetById(1))
  .then(res => console.log('Here is pet id:1 from the api', res.data));

The async-await form is the same thing with a client obtained from getClient():

javascript
import OpenAPIClientAxios from 'openapi-client-axios';

const api = new OpenAPIClientAxios({ definition: 'https://example.com/api/openapi.json' });
api.init();

async function createPet() {
  const client = await api.getClient();
  const res = await client.createPet(null, { name: 'Garfield' });
  console.log('Pet created', res.data);
}

The interesting detail in the first example is the method name, getPetById, which is not a name the library could have invented. It comes from the definition.

Operation methods are named after the operationIds

The client uses the operationIds in OpenAPI v3 definitions to call API operations. After initializing OpenAPIClientAxios, an axios client instance extended with OpenAPI capabilities is exposed, initialised with the baseURL from the OpenAPI definitions and extended with extra operation methods for calling API operations. It also has a reference to OpenAPIClientAxios at client.api.

javascript
const api = new OpenAPIClientAxios({ definition: 'https://example.com/api/openapi.json' });
api.init().then((client) => {
  client.updatePet(1, { age: 12 });
});

Because the method names come from the specification, a client method exists only if the operation declares an operationId. That is a hard requirement to state plainly, because it means the quality of the client depends on the quality of the API description, and a description that omits operationIds gives you a client with no operation methods at all.

The methods take three arguments, and the shape is uniform:

javascript
client.operationId(parameters?, data?, config?)

The first is parameters, and there are three ways to pass them. A named object is the clearest:

javascript
// GET /pets/{petId}
client.getPet({ petId: 1 })

For syntactic sugar you can specify a single implicit parameter value, in which case the library looks for the first required parameter for the operation, which is usually a path parameter:

javascript
// GET /pets/{petId} - getPet
client.getPet(1)

Or you can pass them as an array, which is the form that lets you set custom parameters the spec does not define:

javascript
// GET /pets?search=Garfield - searchPets
client.searchPets([{ name: 'search', value: 'Garfield', in: 'query' }])

The parameter type can be query, header, path or cookie, and the array form is what makes the last two reachable.

The second argument is the request payload, and the third is an AxiosRequestConfig where you can override headers, timeout, withCredentials and many more. The payload can be complex, such as Node.js streams or FormData supported by Axios, and it can be null when an operation takes no parameters.

A paths dictionary for when operationIds will not do

There is a second way to reach an operation, and it exists for a specific reason.

The library allows calling API operations via their path and HTTP method, using the paths dictionary:

javascript
client.paths['/pets'].get(); // GET /pets, same as calling client.getPets()
client.paths['/pets'].post(); // POST /pets
client.paths['/pets/{petId}'].put(1); // PUT /pets/1
client.paths['/pets/{petId}/owner/{ownerId}'].get({ petId: 1, ownerId: 2 }) ; // GET /pets/1/owner/2

This allows calling operation methods without using their operationIds, which may be sometimes preferred. That last clause is the reason to keep the feature. A description where operationIds are missing, duplicated or inconsistent still produces a working client through the paths dictionary, and the path plus method is what the HTTP layer actually needs.

The dictionary is also the escape hatch for a client that has to call something the description does not cover, since the path and method are known to you and the shape of the request is yours to define.

For the common case the operationId methods are the better interface, because they are what the TypeScript definitions are generated from, so the two stay in step. The paths dictionary is what you reach for when the spec and the code have to diverge.

TypeScript types come from a separate typegen command

The type safety story is the part of this library that needs the most care, and the documentation is honest about the shape of it.

The library comes with a CLI command, openapicmd typegen, to generate TypeScript types for type safety and code autocomplete. The command is:

code
npx openapicmd typegen ./openapi.yaml > src/types/openapi.d.ts

The output of typegen exports a type called Client, which can be used for instances created with OpenAPIClientAxios, so the generated type and the runtime client line up by name.

The key point is that generation is a separate step from runtime. The client builds itself from the definition at run time, and the types are produced by a command you run and commit. That means the two can drift, and it means the typegen output belongs in your repository alongside your source, treated as a build artefact that is regenerated when the API changes.

The package metadata shows how that separation is expressed in the dependency list. The runtime dependencies are bath-es5, dereference-json-schema and openapi-types, so the library does its own schema dereferencing rather than pulling in a full validator, and axios and js-yaml are peer dependencies at axios 0.25.0 or newer and js-yaml 4.1.0 or newer, which means the host application chooses the axios version.

That peer dependency arrangement is a deliberate choice worth noting. Since axios is a peer, the version in your application is the version the client runs against, so an axios major upgrade is also a client upgrade, and the 6.0.0 release named axios v1 support is the marker of that transition.

The development dependencies tell you how the library is tested: jest with ts-jest, axios-mock-adapter for stubbing requests, msw for mocking at the network level, json-schema and json-schema-deref-sync as fixtures, and prettier with a separate lint script that checks both src and the test directory. The repository uses husky for the commit hooks and carries a CODE_OF_CONDUCT.md, a SECURITY.md and a DOCS.md at the root.

The release line has been quiet since 2023

The maintenance picture is the thing to weigh before choosing this over a generated client.

The three most recent release tags are 7.0.0 from 2023-02-11, titled Remove SwaggerParser, 6.1.0 from 2023-01-14, titled remove node https and http dependencies, and 6.0.0 from 2022-11-14, titled axios v1 support. The titles are unusually informative, because they are the changelog in the tag names: one dropped the bundled parser, one removed the Node http and https dependencies, one added axios v1 support.

Against that, the package metadata in the repository declares version 7.9.1, which is a good deal higher than the 7.0.0 tag. The repository is not archived, the default branch is main, and the last push was on 2026-10-09, two weeks before the current date. So the code is being worked on, and the version has moved, but there is no tagged release reflecting the current state.

That combination, a maintained main branch with a stale release tag, is a pattern to be careful with. A consumer who installs openapi-client-axios from npm gets whatever was last published, which may predate the fixes in the repository, and the version gap between 7.0.0 and 7.9.1 is wide enough that the axios v1 support and the dependency removals in between are the changes most likely to matter for a working integration.

The project is also part of a wider ecosystem. The homepage is openapistack.co, the readme says the documentation has moved there, and the project publishes the list of organisations using it. The repository has a buy me a coffee link and a sponsor link for the maintainer, so the funding is individual rather than institutional, which is worth weighing against the age of the last tagged release.

Editorial conclusion

openapi-client-axios suits a browser or Node application that consumes several OpenAPI-described services and wants one client shape across all of them without a build step, and it suits a team that wants the OpenAPI definition to stay the single source of truth. It does not suit a project that needs guaranteed type safety without a separate generation step, since the runtime client and the generated types are produced separately, and it does not suit a server that must not fetch a schema at startup. Before adopting it, run the typegen command into your types directory and commit the result, and check that your API actually uses operationIds, because the operation methods are named after them.

Frequently asked questions

What does openapi-client-axios do?

It is a JavaScript client library for consuming OpenAPI enabled APIs with axios, types included. It creates API clients from OpenAPI v3 definitions at runtime with no generated code, generates TypeScript definitions with a separate typegen command, and is isomorphic, working in both browser and Node.js.

How do I call an API operation with openapi-client-axios?

Operation methods are named after the operationIds in the definition and take three arguments: client.operationId(parameters?, data?, config?). Parameters can be a named object, a single implicit value for the first required parameter, or an array for custom parameters not defined in the spec, with query, header, path and cookie supported.

How do I get TypeScript types for an openapi-client-axios client?

Run the openapicmd typegen command, for example npx openapicmd typegen ./openapi.yaml > src/types/openapi.d.ts. The output exports a type called Client, which corresponds to instances created with OpenAPIClientAxios, and the generated file is intended to be committed to your repository.

Can I call an operation without using its operationId?

Yes. The paths dictionary lets you call operations by path and HTTP method, for example client.paths['/pets'].get() or client.paths['/pets/{petId}'].put(1), which the documentation says may sometimes be preferred when the operationIds are missing or unsuitable.

Official sources

  1. License: MIT
  2. openapistack/openapi-client-axios on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/openapistack-openapi-client-axios.svg)](https://hysenlabs.com/projects/openapistack-openapi-client-axios)

Was this useful?