Documentation

OpenAPI Sync is a powerful developer tool that automates the generation of TypeScript types, API clients (Fetch, Axios, React Query, SWR, RTK Query), runtime validation schemas (Zod, Yup, Joi), and endpoint definitions from your OpenAPI specifications in real-time.

Latest Version: 5.0.0 - Major improvements to client generation with bug fixes, better TypeScript support, and enhanced developer experience!

Getting Started with OpenAPI Sync

Duration: 0:10

Learn the basics of OpenAPI Sync and how it can automate your API development workflow.

Watch on YouTube

Installation

Installation & Setup

Duration: 0:10

Step-by-step guide to installing and configuring OpenAPI Sync in your project.

Watch on YouTube

Install OpenAPI Sync using your preferred package manager:

bash
# NPM
npm install openapi-sync

# Yarn
yarn add openapi-sync

# PNPM
pnpm add openapi-sync

# Global Installation
npm install -g openapi-sync

# Direct Usage (No Installation)
npx openapi-sync

Quick Start

Quick Start Tutorial

Duration: 0:10

Get up and running with OpenAPI Sync in under 5 minutes with this quick start guide.

Watch on YouTube

1. Create Configuration

Create a configuration file in your project root:

json
// openapi.sync.json
{
  "refetchInterval": 5000,
  "folder": "./src/api",
  "api": {
    "petstore": "https://petstore3.swagger.io/api/v3/openapi.json"
  }
}

2. Run Sync Command

bash
npx openapi-sync

3. Use Generated Code

typescript
import { getPetById } from "./src/api/petstore/endpoints";
import { IPet } from "./src/api/petstore/types";

// Use the endpoint URL
const petUrl = getPetById("123"); // Returns: "/pet/123"

// Use the generated types
const pet: IPet = {
  id: 1,
  name: "Fluffy",
  status: "available"
};

Basic Configuration

Basic Configuration

Duration: 0:10

Learn how to configure OpenAPI Sync with JSON, TypeScript, or JavaScript config files.

Watch on YouTube

OpenAPI Sync supports multiple configuration formats:

  • openapi.sync.json - JSON format
  • openapi.sync.ts - TypeScript format
  • openapi.sync.js - JavaScript format

Configuration Options

PropertyTypeDescription
refetchIntervalnumberMilliseconds between API refetches (dev only)
folderstringOutput directory for generated files
apiRecord<string, string>Map of API names to OpenAPI spec URLs
servernumber | stringServer index or custom server URL

Folder Splitting

Folder Splitting & Organization

Duration: 0:10

Organize your generated code by tags or custom logic for better project structure.

Watch on YouTube

Organize your generated code into folders based on tags or custom logic.

Split by Tags

typescript
folderSplit: {
  byTags: true  // Creates folders like admin/, user/, pet/
}

Custom Folder Logic

typescript
folderSplit: {
  customFolder: ({ method, path, tags, operationId }) => {
    // Admin endpoints go to admin folder
    if (tags?.includes("admin")) return "admin";
    
    // API versioning
    if (path.startsWith("/api/v1/")) return "v1";
    if (path.startsWith("/api/v2/")) return "v2";
    
    // Method-based organization
    if (method === "GET") return "read";
    if (method === "POST" || method === "PUT") return "write";
    
    return null; // Use default structure
  }
}

Generated Structure

text
src/api/
├── petstore/
│   ├── admin/
│   │   ├── endpoints.ts
│   │   └── types.ts
│   ├── user/
│   │   ├── endpoints.ts
│   │   └── types.ts
│   └── pet/
│       ├── endpoints.ts
│       └── types.ts
└── shared.ts

Validation Schemas

Runtime Validation with Zod, Yup & Joi

Duration: 0:10

Generate and use runtime validation schemas for type-safe API requests.

Watch on YouTube

Generate runtime validation schemas using Zod, Yup, or Joi from your OpenAPI specification.

Configuration

typescript
validations: {
  library: "zod",  // "zod" | "yup" | "joi"
  generate: {
    query: true,   // Generate query parameter validations
    dto: true      // Generate request body validations
  },
  name: {
    prefix: "I",
    suffix: "Schema",
    useOperationId: true
  }
}

Installation

bash
# For Zod
npm install zod

# For Yup
npm install yup

# For Joi
npm install joi

Usage Example

typescript
import { IAddPetDTOSchema } from "./src/api/petstore/validation";
import { z } from "zod";

// Validate request body
try {
  const validatedData = IAddPetDTOSchema.parse(req.body);
  // Data is now validated and typed
} catch (error) {
  if (error instanceof z.ZodError) {
    console.error("Validation errors:", error.errors);
  }
}

Express Middleware

typescript
import { Request, Response, NextFunction } from "express";
import { z } from "zod";

export const validate = <T extends z.ZodTypeAny>(schema: T) => {
  return (req: Request, res: Response, next: NextFunction) => {
    try {
      schema.parse(req.body);
      next();
    } catch (error) {
      if (error instanceof z.ZodError) {
        res.status(400).json({
          error: "Validation failed",
          details: error.errors
        });
      }
    }
  };
};

// Usage
import { IAddPetDTOSchema } from "./api/validation";
router.post("/pet", validate(IAddPetDTOSchema), handler);

Custom Code Preservation

Custom Code Preservation

Duration: 0:10

Learn how to add custom code that survives regeneration using special markers.

Watch on YouTube

Add your own custom code that will survive when files are regenerated.

Configuration

typescript
customCode: {
  enabled: true,              // Enable custom code preservation
  position: "bottom",         // "top" | "bottom" | "both"
  markerText: "CUSTOM CODE",  // Custom marker text
  includeInstructions: true   // Include helpful instructions
}

Usage

typescript
// endpoints.ts (after generation)
export const getPet = (petId: string) => `/pet/${petId}`;

// 🔒 CUSTOM CODE START
// Add your custom code here - it will be preserved
export const legacyGetPet = (id: string) => `/api/v1/pet/${id}`;

export const buildPetUrl = (petId: string, includePhotos: boolean) => {
  const base = getPet(petId);
  return includePhotos ? `${base}?include=photos` : base;
};
// 🔒 CUSTOM CODE END

export const updatePet = (petId: string) => `/pet/${petId}`;

Endpoint Filtering

Endpoint Filtering & Selection

Duration: 0:10

Filter endpoints by tags, paths, or regex patterns to control what gets generated.

Watch on YouTube

Control which endpoints are included in code generation.

Exclude Endpoints

typescript
endpoints: {
  exclude: {
    // Exclude by tags
    tags: ["deprecated", "internal"],
    
    // Exclude specific endpoints
    endpoints: [
      { path: "/admin/users", method: "DELETE" },
      { regex: "^/internal/.*", method: "GET" },
      { path: "/debug" }  // All methods
    ]
  }
}

Include Only Specific Endpoints

typescript
endpoints: {
  include: {
    // Include only public endpoints
    tags: ["public"],
    
    // Include specific endpoints
    endpoints: [
      { path: "/public/users", method: "GET" },
      { regex: "^/public/.*" }
    ]
  }
}

API Client Generation

Automatically generate fully-typed API clients and hooks for popular libraries directly from your OpenAPI specifications.

Generate clients for Fetch, Axios, React Query, SWR, and RTK Query with full TypeScript support!

API Client Generation Overview

Duration: 0:10

Introduction to generating fully-typed API clients from your OpenAPI specification.

Watch on YouTube

Supported Client Types

  • fetch - Native browser Fetch API with TypeScript types
  • axios - Axios client with interceptors and error handling
  • react-query - React Query/TanStack Query hooks (v4 & v5)
  • swr - SWR hooks for React
  • rtk-query - Redux Toolkit Query API slice

Basic Usage

bash
# Generate Fetch client
npx openapi-sync generate-client --type fetch

# Generate Axios client
npx openapi-sync generate-client --type axios

# Generate React Query hooks
npx openapi-sync generate-client --type react-query

# Generate SWR hooks
npx openapi-sync generate-client --type swr

# Generate RTK Query API
npx openapi-sync generate-client --type rtk-query

Filter by Tags or Endpoints

Generate clients for specific endpoints only:

bash
# Filter by tags
npx openapi-sync generate-client --type fetch --tags pets,users

# Filter by endpoint names
npx openapi-sync generate-client --type axios --endpoints getPetById,createPet

# Generate for specific API
npx openapi-sync generate-client --type react-query --api petstore

# Specify output directory
npx openapi-sync generate-client --type swr --output ./src/clients

# Set base URL
npx openapi-sync generate-client --type fetch --base-url https://api.example.com

React Query Example

Complete example using React Query hooks:

typescript
// 1. Generate the client
// npx openapi-sync generate-client --type react-query

// 2. Setup in your app
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import apiClient from "./api/petstore/client/client";

// Configure API client
apiClient.updateConfig({
  baseURL: "https://api.example.com",
});
apiClient.setAuthToken("your-auth-token");

const queryClient = new QueryClient();

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <YourComponent />
    </QueryClientProvider>
  );
}

// 3. Use in components
import { useGetPetById, useCreatePet } from "./api/petstore/client/hooks";

function PetDetails({ petId }: { petId: string }) {
  // Query hook for GET requests
  const { data, isLoading, error } = useGetPetById({ petId });

  // Mutation hook for POST/PUT/PATCH/DELETE
  const createPet = useCreatePet({
    onSuccess: (newPet) => {
      console.log("Pet created:", newPet);
    },
  });

  const handleCreate = () => {
    createPet.mutate({
      data: {
        name: "Fluffy",
        species: "cat",
      },
    });
  };

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <h1>{data?.name}</h1>
      <p>Status: {data?.status}</p>
      <button onClick={handleCreate}>Create New Pet</button>
    </div>
  );
}

Fetch Client Example

typescript
import { setApiConfig, getPetById, createPet } from "./api/petstore/client";

// Configure the client
setApiConfig({
  baseURL: "https://api.example.com",
  auth: { token: "your-token" },
  headers: {
    "X-Custom-Header": "value",
  },
});

// Use the client
async function fetchPet(petId: string) {
  try {
    const pet = await getPetById({ petId });
    console.log("Pet:", pet);
  } catch (error) {
    if (error instanceof ApiError) {
      console.error("API Error:", error.statusCode, error.response);
    }
  }
}

async function addNewPet() {
  const newPet = await createPet({
    data: {
      name: "Max",
      species: "dog",
      age: 3,
    },
  });
  console.log("Created:", newPet);
}

Axios Client Example

typescript
import apiClient from "./api/petstore/client";

// Configure the client
apiClient.updateConfig({
  baseURL: "https://api.example.com",
  timeout: 10000,
  headers: {
    "X-App-Version": "1.0.0",
  },
});

// Set auth token
apiClient.setAuthToken("your-auth-token");

// Use the client
async function example() {
  // GET request
  const pet = await apiClient.getPetById({ petId: "123" });
  
  // POST request
  const newPet = await apiClient.createPet({
    data: {
      name: "Buddy",
      species: "dog",
    },
  });
  
  // PUT request
  await apiClient.updatePet(
    { petId: "123" },
    { name: "Buddy Updated" }
  );
  
  // DELETE request
  await apiClient.deletePet({ petId: "123" });
}

SWR Hooks Example

typescript
import { useGetPetById, useCreatePet } from "./api/petstore/client/hooks";

function PetProfile({ petId }: { petId: string }) {
  // SWR automatically handles caching, revalidation, and more
  const { data, error, isLoading, mutate } = useGetPetById({ petId });

  const { trigger, isMutating } = useCreatePet();

  const handleCreate = async () => {
    try {
      const newPet = await trigger({
        arg: {
          data: {
            name: "Charlie",
            species: "cat",
          },
        },
      });
      // Revalidate the pet list
      mutate();
    } catch (err) {
      console.error("Failed to create pet:", err);
    }
  };

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error loading pet</div>;

  return (
    <div>
      <h2>{data?.name}</h2>
      <button onClick={handleCreate} disabled={isMutating}>
        {isMutating ? "Creating..." : "Create New Pet"}
      </button>
    </div>
  );
}

RTK Query Example

typescript
// 1. Setup store
import { configureStore } from "@reduxjs/toolkit";
import { apiApi } from "./api/petstore/client/api";

export const store = configureStore({
  reducer: {
    [apiApi.reducerPath]: apiApi.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(apiApi.middleware),
});

// 2. Use in components
import { useGetPetByIdQuery, useCreatePetMutation } from "./api/petstore/client/api";

function PetCard({ petId }: { petId: string }) {
  const { data, isLoading, error } = useGetPetByIdQuery({ 
    params: { petId } 
  });
  
  const [createPet, { isLoading: isCreating }] = useCreatePetMutation();

  const handleCreate = async () => {
    try {
      await createPet({
        data: {
          name: "Luna",
          species: "cat",
        },
      }).unwrap();
      alert("Pet created!");
    } catch (err) {
      console.error("Failed:", err);
    }
  };

  return (
    <div>
      {isLoading && <div>Loading...</div>}
      {error && <div>Error!</div>}
      {data && (
        <div>
          <h3>{data.name}</h3>
          <p>{data.species}</p>
        </div>
      )}
      <button onClick={handleCreate} disabled={isCreating}>
        Create Pet
      </button>
    </div>
  );
}

Generated File Structure

text
api/
└── petstore/
    ├── client/
    │   ├── client.ts      # Base API client
    │   ├── hooks.ts       # React Query/SWR hooks
    │   ├── api.ts         # RTK Query API (if applicable)
    │   ├── index.ts       # Exports
    │   └── README.md      # Usage documentation
    ├── endpoints.ts
    ├── types/
    │   ├── index.ts
    │   └── shared.ts
    └── validations.ts

Configuration Options

typescript
// openapi.sync.ts
import { IConfig } from "openapi-sync/types";

const config: IConfig = {
  folder: "./src/api",
  api: {
    petstore: "https://petstore3.swagger.io/api/v3/openapi.json",
  },
  // Client generation configuration
  clientGeneration: {
    enabled: true,
    type: "react-query",
    baseURL: "https://api.example.com",
    tags: ["pets", "users"],  // Optional: filter by tags
    endpoints: ["getPetById"], // Optional: specific endpoints
    auth: {
      type: "bearer",
      in: "header",
    },
    errorHandling: {
      generateErrorClasses: true,
    },
    reactQuery: {
      version: 5,
      mutations: true,
      infiniteQueries: false,
    },
  },
};

export default config;

Custom Code Preservation

Generated clients preserve your custom code during regeneration:

typescript
// client.ts (Generated)

// Auto-generated client code...

// ============================================================
// 🔒 CUSTOM CODE START
// Add your custom code below this line
// This section will be preserved during regeneration
// ============================================================

// Your custom helper functions
export function buildPaginatedUrl(
  baseUrl: string,
  page: number,
  limit: number
) {
  return `${baseUrl}?page=${page}&limit=${limit}`;
}

// Custom interceptors
export function setupCustomInterceptors() {
  // Your custom logic
}

// 🔒 CUSTOM CODE END
// ============================================================

CLI Options Reference

OptionDescriptionExample
--type, -tClient type to generate (required)fetch, axios, react-query, swr, rtk-query
--api, -aSpecific API from config--api petstore
--tagsFilter by endpoint tags--tags pets,users
--endpoints, -eFilter by endpoint names--endpoints getPetById,createPet
--output, -oOutput directory--output ./src/clients
--base-url, -bBase URL for requests--base-url https://api.example.com

New in v5.0.0: All client generators now include comprehensive inline documentation, better ESLint compliance, and improved folder splitting support!

RTK Query Enhancements (v5.0.0)

Simplified Redux Store Setup

When using folder splitting, RTK Query now generates an apis.ts file with a helper object that makes Redux store configuration incredibly simple:

typescript
// Before v5.0.0 (Complex setup)
import { configureStore } from '@reduxjs/toolkit';
import { petsApi } from './pets/api';
import { usersApi } from './users/api';
import { ordersApi } from './orders/api';

export const store = configureStore({
  reducer: {
    [petsApi.reducerPath]: petsApi.reducer,
    [usersApi.reducerPath]: usersApi.reducer,
    [ordersApi.reducerPath]: ordersApi.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware()
      .concat(petsApi.middleware)
      .concat(usersApi.middleware)
      .concat(ordersApi.middleware),
});
typescript
// After v5.0.0 (Simple setup!)
import { configureStore } from '@reduxjs/toolkit';
import { setupApiStore } from './api/petstore/apis';

export const store = configureStore({
  reducer: setupApiStore.reducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(setupApiStore.middleware),
});

// That's it! All API slices are automatically configured ✨

Unique Reducer Paths

Each API slice now has a unique reducerPath based on its folder name, preventing conflicts:

typescript
// Generated pets/api.ts
const petsApi = createApi({
  reducerPath: 'petsApi',  // ✅ Unique!
  // ...
});

// Generated users/api.ts
const usersApi = createApi({
  reducerPath: 'usersApi',  // ✅ Unique!
  // ...
});

// No more "Duplicate property" TypeScript errors!

Default Exports for Better Imports

API slices now export as default, making imports cleaner:

typescript
// Clean default import
import petsApi from './pets/api';
import { useGetPetsQuery } from './pets/api';

// Or use the aggregated apis.ts
import { petsApi, useGetPetsQuery } from './apis';

SWR Improvements (v5.0.0)

Fixed Mutation Type Errors

SWR mutation hooks now have correct TypeScript types, fixing the double-nesting issue:

typescript
// v5.0.0 - Correct types! ✅
export function useCreatePet(
  config?: SWRMutationConfiguration<
    Pet,
    Error,
    string,
    { data: PetRequest }  // Correct: single level
  >
) {
  return useSWRMutation(
    'createPet',
    async (_, { arg }: { arg: { data: PetRequest } }) => {
      return apiClient.createPet(arg);
    },
    config
  );
}

// Usage - works perfectly!
const { trigger } = useCreatePet();
await trigger({ arg: { data: { name: 'Fluffy' } } });

Comprehensive Inline Documentation

Every generated SWR hooks file now includes 230+ lines of usage examples and patterns:

typescript
/**
 * SWR Hooks - Complete Usage Guide
 * 
 * ## Quick Start
 * 
 * 1. Configure SWR globally:
 * ```typescript
 * <SWRConfig value={{ revalidateOnFocus: false }}>
 *   {children}
 * </SWRConfig>
 * ```
 * 
 * ## Examples
 * 
 * ### Reading Data (GET)
 * ```typescript
 * const { data, error, isLoading } = useGetPets();
 * ```
 * 
 * ### Creating Data (POST)
 * ```typescript
 * const { trigger, isMutating } = useCreatePet();
 * await trigger({ arg: { data: { name: 'Luna' } } });
 * ```
 * 
 * ### Optimistic Updates
 * ```typescript
 * revalidate({ ...data, name: newName }, false);
 * await trigger({ arg: { ... } });
 * await revalidate(); // Sync with server
 * ```
 * 
 * [... 200+ more lines of examples ...]
 */

Fetch Client Fixes (v5.0.0)

Fixed Naming Conflicts

Endpoint imports are now automatically aliased to prevent naming conflicts:

typescript
// Generated imports (aliased to avoid conflicts)
import {
  getPets as getPets_endpoint,
  getPetById as getPetById_endpoint,
  createPet as createPet_endpoint,
} from './endpoints';

// Generated functions (no conflict!)
export async function getPets() {
  const _url = getPets_endpoint;  // Uses aliased import
  return fetchAPI(_url, { method: 'GET' });
}

export async function getPetById(params: { url: { id: string } }) {
  const _url = getPetById_endpoint(params.url.id);  // Uses aliased import
  return fetchAPI(_url, { method: 'GET' });
}

ESLint-Compliant Default Exports

Default exports now use named variables, satisfying ESLint rules:

typescript
// v5.0.0 - ESLint compliant! ✅
const apiClient = {
  setApiConfig,
  getPets,
  getPetById,
  createPet,
};

export default apiClient;

// No more "Assign object to variable" ESLint warnings!

File Organization Improvements (v5.0.0)

Non-Folder-Split Mode

When folder splitting is disabled, files are now generated directly at the root level:

text
api/
└── petstore/
    ├── clients.ts       # All API client functions
    ├── hooks.ts         # All React Query/SWR hooks  
    ├── endpoints.ts     # Endpoint definitions
    ├── types.ts         # TypeScript types
    └── validations.ts   # Validation schemas

# Clean, simple structure for smaller APIs!

Folder-Split Mode

With folder splitting, each tag gets its own folder with complete isolation:

text
api/
└── petstore/
    ├── clients.ts       # Aggregates all clients (Fetch/Axios)
    ├── hooks.ts         # Aggregates all hooks (React Query/SWR)
    ├── apis.ts          # Aggregates all APIs (RTK Query) + setupApiStore
    ├── pets/
    │   ├── client.ts    # Pet-specific client
    │   ├── hooks.ts     # Pet-specific hooks
    │   ├── api.ts       # Pet-specific RTK Query API
    │   ├── types.ts     # Pet-specific types
    │   └── endpoints.ts # Pet-specific endpoints
    └── users/
        ├── client.ts
        ├── hooks.ts
        ├── api.ts
        ├── types.ts
        └── endpoints.ts

# Perfect for large APIs with many endpoints!

💡 Migration Tip: To get all these improvements, simply regenerate your clients:

bash
npx openapi-sync generate-client --type [your-type]

All improvements are backwards compatible - your existing code will continue to work!

CLI Usage

CLI Commands & Options

Duration: 0:10

Master the OpenAPI Sync CLI with all available commands and options.

Watch on YouTube
bash
# Sync API types and endpoints
npx openapi-sync

# Generate API client
npx openapi-sync generate-client --type react-query

# Run with custom refetch interval
npx openapi-sync --refreshinterval 30000
npx openapi-sync -ri 30000

# Get help
npx openapi-sync --help
npx openapi-sync generate-client --help

CLI Improvements (v5.0.0)

CLI Arguments Override Config

CLI options now correctly override configuration file settings:

bash
# Config file says type: "fetch"
# But CLI argument takes precedence:
npx openapi-sync generate-client --type rtk-query

# Result: Generates RTK Query (not Fetch) ✅

# This works for all options:
npx openapi-sync generate-client \
  --type swr \
  --base-url https://api.example.com \
  --tags pets,users

# CLI values override config values!

Streamlined Interactive Setup

The interactive setup wizard is now simpler - selecting folder splitting automatically enables tag-based organization:

bash
# npx openapi-sync init

? Organize generated code into folders by OpenAPI tags? Yes
# ✅ Automatically enables byTags: true
# (No extra question needed!)

? Generate API client code? Yes
? Which client type would you like? React Query
# ... continues with setup

Programmatic Usage

Programmatic API Usage

Duration: 0:10

Use OpenAPI Sync programmatically in your Node.js scripts and build tools.

Watch on YouTube
typescript
import { Init } from "openapi-sync";

// Initialize with default config
await Init();

// Initialize with custom options
await Init({
  refetchInterval: 30000
});

// With error handling
try {
  await Init({
    refetchInterval: process.env.NODE_ENV === "development" ? 5000 : 0
  });
  console.log("API types synchronized successfully");
} catch (error) {
  console.error("Failed to sync API types:", error);
}

Troubleshooting

Common Issues & Troubleshooting

Duration: 0:10

Learn how to debug and resolve common issues when using OpenAPI Sync.

Watch on YouTube

Configuration File Not Found

Error: No config found

Solution: Ensure you have one of these files in your project root:openapi.sync.json, openapi.sync.ts, or openapi.sync.js

Network Timeout Errors

Error: timeout of 60000ms exceeded

Solution: The tool includes automatic retry with exponential backoff. Check your internet connection and verify the OpenAPI spec URL is accessible.

TypeScript Compilation Errors

Error: Cannot find module './src/api/petstore/types'

Solution: Ensure the sync process completed successfully and check that the folder path in config is correct.

API Reference

Init(options?: InitOptions)

Initializes OpenAPI sync with the specified configuration.

typescript
import { Init } from "openapi-sync";

await Init({ 
  refetchInterval: 10000 
});

Exported Types

typescript
import {
  IConfig,
  IOpenApiSpec,
  IOpenApSchemaSpec,
  IConfigReplaceWord,
  IConfigExclude,
  IConfigInclude,
  IConfigDoc
} from "openapi-sync/types";

Changelog

Track the evolution of OpenAPI Sync with detailed release notes and version history.

v5.0.0

LATESTOctober 25, 2025

Major improvements to client generation with enhanced TypeScript support, better developer experience, and critical bug fixes

  • 🎉 RTK Query: Simplified Redux store setup with setupApiStore helper (15 lines → 5 lines)
  • RTK Query: Unique reducer paths per folder preventing TypeScript conflicts
  • RTK Query: Default exports for cleaner imports
  • SWR: Fixed mutation hooks type errors (no more double-nesting)
  • 📚 SWR: Added 230+ lines of comprehensive inline documentation and usage examples
  • Fetch: Fixed naming conflicts with aliased endpoint imports (_endpoint suffix)
  • Fetch: ESLint-compliant default exports using named variables
  • 🚀 CLI: Arguments now correctly override config file settings
  • 🎯 CLI: Streamlined interactive setup (auto-enables byTags when folder splitting)
  • 📦 Structure: Non-folder-split mode generates files directly at root (clients.ts, hooks.ts)
  • 🎨 DX: Better TypeScript support across all client types
  • Performance: Optimized code generation and improved error handling

v4.1.0

2024

API Client Generation - Generate fully-typed clients for Fetch, Axios, React Query, SWR, and RTK Query with custom code preservation

v4.0.0

2024

Major release with validation schema generation support (Zod, Yup, Joi) for runtime type validation

v2.1.13

Type definition fixes, clean up tsup build configuration, and introduction of comprehensive unit testing

v2.1.11

Folder splitting configuration for organized code generation by tags or custom logic

v2.1.10

OperationId-based naming for types and endpoints, enhanced filtering and tag support

📖 Full Changelog: For complete release notes and detailed changes, visit the dedicated Changelog page.