# ng-openapi — full documentation
> Concatenated documentation of ng-openapi (https://ng-openapi.dev), an Angular-first OpenAPI client generator created and maintained by Tareq Jami (https://tareqjami.de) of Jami IT (https://jami-it.de), generated from the same sources as the website. See https://ng-openapi.dev/llms.txt for the index and usage rules.
---
## Introduction
ng-openapi is a modern Angular-first OpenAPI client generator that creates type-safe services and interfaces from your OpenAPI specifications. Unlike generic TypeScript generators, ng-openapi is built specifically for Angular developers who want clean, maintainable code that leverages Angular's latest features.
## Quick Example
```bash
# Install ng-openapi
npm install ng-openapi --save-dev
# Generate from OpenAPI spec
ng-openapi -i swagger.json -o ./src/api
```
```typescript
// Use in your Angular app
import { provideDefaultClient } from './api/providers';
export const appConfig: ApplicationConfig = {
providers: [
provideDefaultClient({ basePath: 'https://api.example.com' })
]
};
```
## What's Included
- **TypeScript Interfaces** - Accurate type definitions from your OpenAPI schemas
- **Angular Services** - Injectable services with proper dependency injection
- **HTTP Interceptors** - Automatic date transformation and custom headers
- **Provider Functions** - Easy setup with `provideDefaultClient()`
- **File Utilities** - Download helpers and file handling
- **CLI Tool** - Powerful command-line interface with config file support
See [Generated Output](./guide/generated-code.md) for a tour of every generated file.
## Support the Project
ng-openapi’s mission is to remain the #1 Angular client generation library.
If you’d like to support this journey, feel free to sponsor me with a coffee — after all, we all know a developer’s fuel is coffee 😄
---
# Installation
Install ng-openapi to generate Angular services and TypeScript types from OpenAPI specifications.
## Prerequisites
- **Node.js**: Version 20.0.0 or higher
- **Angular**: Version 15 or higher (peer dependency)
## Install
### Development Dependency (Recommended)
::: code-group
```bash [npm]
npm install ng-openapi --save-dev
```
```bash [yarn]
yarn add ng-openapi --dev
```
```bash [pnpm]
pnpm add ng-openapi --save-dev
```
:::
### Global Installation
```bash
npm install -g ng-openapi
```
## Verify Installation
```bash
ng-openapi --version
```
## Next Step
Continue with the [Quick Start](./quick-start.md) to generate your first client.
---
# Quick Start
Generate Angular services and TypeScript types from your OpenAPI specification.
## Step 1: Prepare Your OpenAPI Specification
You need an OpenAPI/Swagger specification file:
- JSON file (`swagger.json`, `openapi.json`)
- Yaml file (`swagger.yml`, `openapi.yaml`)
## Step 2: Generate API Client
### Using Command Line
```bash
ng-openapi -i ./swagger.json -o ./src/api
```
### Using Configuration File
Create `openapi.config.ts`:
```typescript
import { GeneratorConfig } from "ng-openapi";
const config: GeneratorConfig = {
input: "./swagger.json",
output: "./src/api",
options: {
dateType: "Date",
enumStyle: "enum",
},
};
export default config;
```
Then run:
```bash
ng-openapi -c openapi.config.ts
```
## Step 3: Configure Your Angular App
Add the provider to your `app.config.ts`:
```typescript
import { ApplicationConfig } from "@angular/core";
import { provideHttpClient } from "@angular/common/http";
import { provideDefaultClient } from "./api/providers";
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(),
provideDefaultClient({
basePath: "https://api.example.com",
}),
],
};
```
## Step 4: Use Generated Services
```typescript
import { inject } from "@angular/core";
import { toSignal } from "@angular/core/rxjs-interop";
import { PetsService } from "./api/services";
import { Pet } from "./api/models";
export class PetsComponent {
private readonly petsService = inject(PetsService);
readonly pets = toSignal(this.petsService.listPets());
}
```
## Generated Structure
After generation, you'll have:
```
src/api/
├── models/ # TypeScript interfaces, enums
├── services/ # One Angular service per controller
├── tokens/ # Injection tokens
├── utils/ # Date transformer, download helpers, …
├── providers.ts # provideDefaultClient() setup function
└── index.ts # Main exports
```
See [Generated Output](../guide/generated-code.md) for what every file does.
## Next Steps
- [Configuration Reference](../api/configuration.md) — all generator options at a glance
- [Angular Integration](../guide/angular-integration.md) — providers, interceptors, environments
- [Multiple Clients](../guide/multiple-clients.md) — several APIs in one app
- [Schema Validation](../guide/schema-validation.md) — validate responses at runtime
---
# Angular Integration
Configure ng-openapi providers and services in your Angular application.
## Basic Setup
### Configure Providers
```typescript
import { ApplicationConfig } from "@angular/core";
import { provideHttpClient } from "@angular/common/http";
import { provideDefaultClient } from "./client/providers";
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(),
provideDefaultClient({
basePath: "https://api.example.com",
}),
],
};
```
### Inject Services
```typescript
import { Component, inject } from "@angular/core";
import { UsersService } from "./client/services";
@Component({
selector: "app-users",
template: ``,
})
export class UsersComponent {
private readonly usersService = inject(UsersService);
}
```
## Environment Configuration
```typescript
import { provideDefaultClient } from "./client/providers";
import { environment } from "./environments/environment";
export const appConfig: ApplicationConfig = {
providers: [
provideDefaultClient({
basePath: environment.apiUrl,
}),
],
};
```
## Disable Date Transformation
```typescript
provideDefaultClient({
basePath: "https://api.example.com",
enableDateTransform: false,
});
```
## Manual Configuration
```typescript
import { BASE_PATH } from "./client/tokens";
export const appConfig: ApplicationConfig = {
providers: [{ provide: BASE_PATH, useValue: "https://api.example.com" }],
};
```
## Resources
- [Angular Dependency Injection ↗️](https://angular.dev/guide/di)
- [Angular Providers ↗️](https://angular.dev/guide/di/dependency-injection-providers)
---
# CLI Usage
Generate API clients using the ng-openapi command line interface. This page covers day-to-day workflows; the complete flag list lives in the [CLI reference](../api/cli.md).
## Basic Commands
### Direct Generation
```bash
ng-openapi -i swagger.json -o ./src/api
```
The input can also be a URL:
```bash
ng-openapi -i https://api.example.com/openapi.yaml -o ./src/api
```
### Configuration File
```bash
ng-openapi -c openapi.config.ts
```
### Generate Subcommand
```bash
ng-openapi generate -i swagger.json -o ./src/api
ng-openapi gen -c openapi.config.ts # Short alias
```
## Common Options
### Types Only
```bash
ng-openapi -i swagger.json -o ./src/api --types-only
```
### String Dates
```bash
ng-openapi -i swagger.json -o ./src/api --date-type string
```
## Configuration vs CLI
CLI flags cover the quick cases; everything else (headers, plugins, method naming, validation, …) needs a [configuration file](../api/configuration.md):
```typescript
// openapi.config.ts
import { GeneratorConfig } from "ng-openapi";
const config: GeneratorConfig = {
input: "./swagger.json",
output: "./src/api",
options: {
dateType: "Date",
enumStyle: "enum",
customHeaders: { "X-API-Key": "key" },
responseTypeMapping: { "application/pdf": "blob" },
},
};
export default config;
```
```bash
ng-openapi -c openapi.config.ts
```
## Workflow Recipes
### Generate Before Serving/Building
```json
{
"scripts": {
"generate:client": "ng-openapi -c openapi.config.ts",
"dev": "npm run generate:client && ng serve",
"prebuild": "npm run generate:client",
"build": "ng build"
}
}
```
### Regenerate on Spec Changes
```json
{
"scripts": {
"generate:watch": "nodemon --watch swagger.json --exec 'npm run generate:client'"
}
}
```
### Fetch the Spec First
```json
{
"scripts": {
"fetch:spec": "curl https://api.example.com/swagger.json > swagger.json",
"generate:client": "npm run fetch:spec && ng-openapi -c openapi.config.ts"
}
}
```
Alternatively, point `input` directly at the URL and use [`validateInput`](../api/configuration/validate-input.md) to guard against unexpected spec changes.
### Multiple APIs
```json
{
"scripts": {
"generate:users": "ng-openapi -c users-api.config.ts",
"generate:orders": "ng-openapi -c orders-api.config.ts",
"generate:all": "npm run generate:users && npm run generate:orders"
}
}
```
See [Multiple Clients](./multiple-clients.md) for the full setup.
## Help and Version
```bash
ng-openapi --help
ng-openapi generate --help
ng-openapi --version
```
## Resources
- [CLI Reference](../api/cli.md) — all flags and defaults
- [Configuration Reference](../api/configuration.md) — all config-file properties
- [Generated Output](./generated-code.md) — what lands in your output directory
---
# Date Handling
Work with automatic date transformation features in ng-openapi.
## Automatic Date Transformation
### Configuration
```typescript
// openapi.config.ts
const config: GeneratorConfig = {
options: {
dateType: "Date", // Enables automatic transformation
},
};
```
### Generated Models
```typescript
// Generated interface with Date type
interface User {
id: number;
name: string;
createdAt: Date; // Automatically transformed from ISO string
updatedAt: Date;
}
```
### Usage
```typescript
export class UsersComponent {
private readonly usersService = inject(UsersService);
loadUser(id: number) {
this.usersService.getUserById(id).subscribe((user) => {
// createdAt is already a Date object
console.log(user.createdAt.getFullYear());
console.log(user.createdAt.toLocaleDateString());
});
}
}
```
## String Dates
### Configuration
```typescript
// openapi.config.ts
const config: GeneratorConfig = {
options: {
dateType: "string", // No transformation
},
};
```
### Generated Models
```typescript
// Generated interface with string type
interface User {
id: number;
name: string;
createdAt: string; // ISO string format
updatedAt: string;
}
```
### Usage
```typescript
export class UsersComponent {
loadUser(id: number) {
this.usersService.getUserById(id).subscribe((user) => {
// Convert manually when needed
const createdDate = new Date(user.createdAt);
console.log(createdDate.getFullYear());
});
}
}
```
## Date Transformer Interceptor
### Disable Transformation
```typescript
// Disable in provider
provideDefaultClient({
basePath: "https://api.example.com",
enableDateTransform: false,
});
```
### Manual Setup
`DateInterceptor` is class-based, so it is registered through the `HTTP_INTERCEPTORS` multi-provider (`withInterceptors` only accepts functional interceptors):
```typescript
import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from "@angular/common/http";
import { DateInterceptor } from "./client/utils/date-transformer";
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(withInterceptorsFromDi()),
{ provide: HTTP_INTERCEPTORS, useClass: DateInterceptor, multi: true },
],
};
```
## Which Strings Are Detected as Dates?
The interceptor only converts strings matching a strict full ISO 8601 date-time pattern (`ISO_DATE_REGEX`), so bare years or numeric IDs are never accidentally turned into `Date` objects. The exact pattern and all recognized formats are documented in the [Date Transformer reference](../api/utilities/date-transformer.md#recognized-formats).
### Custom Date Regex
If your API returns a format the default pattern doesn't cover, pass your own
regex via the provider — no need to copy `date-transformer.ts`:
```typescript
provideDefaultClient({
basePath: "https://api.example.com",
// Use any pattern you like; it overrides ISO_DATE_REGEX
dateTransformRegex: /your-custom-pattern/,
});
```
`transformDates` and `DateInterceptor` also accept the regex directly, so you can
reuse them in a manual interceptor setup:
```typescript
new DateInterceptor(/your-custom-regex/);
transformDates(responseBody, /your-custom-regex/);
```
## Resources
- [Date Transformer reference](../api/utilities/date-transformer.md) — recognized formats, generated source, manual setup
- [JavaScript Date ↗️](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)
- [Angular HTTP Interceptors ↗️](https://angular.dev/guide/http/interceptors)
---
# File Downloads
Use the built-in file download utilities with generated services.
## Basic Usage
### downloadFileOperator
```typescript
import { Component, inject } from "@angular/core";
import { downloadFileOperator } from "./client/utils/file-download";
import { ReportsService } from "./client/services";
export class ReportsComponent {
private readonly reportsService = inject(ReportsService);
downloadReport(reportId: number) {
this.reportsService.getReportPdf(reportId).pipe(downloadFileOperator("report.pdf")).subscribe();
}
}
```
### Dynamic Filenames
```typescript
downloadReport(reportId: number) {
this.reportsService.getReportPdf(reportId)
.pipe(
downloadFileOperator(`report-${reportId}.pdf`)
)
.subscribe();
}
```
### Function-Based Filenames
```typescript
downloadReport(reportId: number) {
this.reportsService.getReportPdf(reportId)
.pipe(
downloadFileOperator((blob: Blob) => {
const date = new Date().toISOString().split('T')[0];
return `report-${reportId}-${date}.pdf`;
})
)
.subscribe();
}
```
## Extract Filename from Headers
### extractFilenameFromContentDisposition
```typescript
import { HttpClient, HttpResponse } from "@angular/common/http";
import { extractFilenameFromContentDisposition, downloadFile } from "./client/utils/file-download";
export class FilesService {
private readonly http = inject(HttpClient);
downloadWithHeaders(url: string) {
this.http
.get(url, {
responseType: "blob",
observe: "response",
})
.subscribe((response: HttpResponse) => {
const contentDisposition = response.headers.get("Content-Disposition");
const filename = extractFilenameFromContentDisposition(contentDisposition, "download.pdf");
if (response.body) {
downloadFile(response.body, filename);
}
});
}
}
```
## Direct Download Function
### downloadFile
```typescript
import { downloadFile } from "./client/utils/file-download";
// Direct usage without operator
this.reportsService.getReportPdf(reportId).subscribe((blob) => {
downloadFile(blob, "report.pdf");
});
```
## Response Type Mapping
Configure blob responses in your OpenAPI config:
```typescript
// openapi.config.ts
const config: GeneratorConfig = {
options: {
responseTypeMapping: {
"application/pdf": "blob",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "blob",
},
},
};
```
## Resources
- [RxJS Operators ↗️](https://rxjs.dev/guide/operators)
- [Angular HTTP Client ↗️](https://angular.dev/guide/http)
---
# Generated Output
What ng-openapi actually writes into your output directory, file by file. This is the canonical reference for the generated structure — other pages link here instead of repeating it.
## The Full Tree
With the default configuration (`generateServices: true`, `dateType: "Date"`):
```