Documentation
OpenAPI Sync is a powerful developer tool that automates the generation of TypeScript types, runtime validation schemas (Zod, Yup, Joi), and endpoint definitions from your OpenAPI specifications in real-time.
Latest Version: 4.0.0 - Now with Zod, Yup & Joi validation support
Installation
Install OpenAPI Sync using your preferred package manager:
# 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
1. Create Configuration
Create a configuration file in your project root:
// openapi.sync.json
{
"refetchInterval": 5000,
"folder": "./src/api",
"api": {
"petstore": "https://petstore3.swagger.io/api/v3/openapi.json"
}
}
2. Run Sync Command
npx openapi-sync
3. Use Generated Code
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
OpenAPI Sync supports multiple configuration formats:
openapi.sync.json
- JSON formatopenapi.sync.ts
- TypeScript formatopenapi.sync.js
- JavaScript format
Configuration Options
Property | Type | Description |
---|---|---|
refetchInterval | number | Milliseconds between API refetches (dev only) |
folder | string | Output directory for generated files |
api | Record<string, string> | Map of API names to OpenAPI spec URLs |
server | number | string | Server index or custom server URL |
Folder Splitting
Organize your generated code into folders based on tags or custom logic.
Split by Tags
folderSplit: {
byTags: true // Creates folders like admin/, user/, pet/
}
Custom Folder Logic
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
src/api/
├── petstore/
│ ├── admin/
│ │ ├── endpoints.ts
│ │ └── types.ts
│ ├── user/
│ │ ├── endpoints.ts
│ │ └── types.ts
│ └── pet/
│ ├── endpoints.ts
│ └── types.ts
└── shared.ts
Validation Schemas
Generate runtime validation schemas using Zod, Yup, or Joi from your OpenAPI specification.
Configuration
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
# For Zod
npm install zod
# For Yup
npm install yup
# For Joi
npm install joi
Usage Example
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
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
Add your own custom code that will survive when files are regenerated.
Configuration
customCode: {
enabled: true, // Enable custom code preservation
position: "bottom", // "top" | "bottom" | "both"
markerText: "CUSTOM CODE", // Custom marker text
includeInstructions: true // Include helpful instructions
}
Usage
// 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
Control which endpoints are included in code generation.
Exclude Endpoints
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
endpoints: {
include: {
// Include only public endpoints
tags: ["public"],
// Include specific endpoints
endpoints: [
{ path: "/public/users", method: "GET" },
{ regex: "^/public/.*" }
]
}
}
CLI Usage
# Run with default configuration
npx openapi-sync
# Run with custom refetch interval
npx openapi-sync --refreshinterval 30000
npx openapi-sync -ri 30000
# Get help
npx openapi-sync --help
Programmatic Usage
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
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.
import { Init } from "openapi-sync";
await Init({
refetchInterval: 10000
});
Exported Types
import {
IConfig,
IOpenApiSpec,
IOpenApSchemaSpec,
IConfigReplaceWord,
IConfigExclude,
IConfigInclude,
IConfigDoc
} from "openapi-sync/types";
Changelog
v4.0.0
Major release with validation schema generation support (Zod, Yup, Joi)
v2.1.13
Fix dts type fixes and Clean up tsup build config and introduction of unit testing
v2.1.11
Folder splitting configuration for organized code generation
v2.1.10
OperationId-based naming for types and endpoints, enhanced filtering and tag support