Self-Documenting APIs From Your Decorators
OpenAPI & Swagger
`@nestjs/swagger` reads your controllers and DTOs and generates an interactive OpenAPI documentation page. Almost no extra effort.
What you'll learn
- Install @nestjs/swagger
- Set up SwaggerModule in main.ts
- Annotate controllers and DTOs
Half the value of writing typed DTOs and decorated controllers is that
something can generate API documentation from them. @nestjs/swagger
does exactly that — it produces an OpenAPI spec and a Swagger UI page
with very little extra code.
Install
npm i @nestjs/swagger Hook It Into main.ts
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('My API')
.setVersion('1.0')
.addBearerAuth()
.build();
const doc = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('docs', app, doc);
await app.listen(3000);
}
bootstrap(); Visit http://localhost:3000/docs and you’ll see an interactive UI
listing every route — with “Try it out” buttons that actually call your
API.
Decorate Controllers and DTOs
The generator infers what it can from TypeScript, but explicit decorators give richer docs.
import { ApiTags, ApiResponse, ApiBearerAuth } from '@nestjs/swagger';
@ApiTags('users')
@ApiBearerAuth()
@Controller('users')
export class UsersController {
@Get(':id')
@ApiResponse({ status: 200, type: UserDto })
@ApiResponse({ status: 404, description: 'User not found' })
findOne(@Param('id') id: string) { /* ... */ }
} import { ApiProperty } from '@nestjs/swagger';
import { IsEmail, IsString } from 'class-validator';
export class CreateUserDto {
@ApiProperty({ example: 'a@b.com' })
@IsEmail()
email: string;
@ApiProperty({ minLength: 2 })
@IsString()
name: string;
} class-validator rules feed into the spec automatically — minLength,
required, format — so consumers see the same constraints the server
enforces.
The CLI Plugin (Recommended)
Adding @ApiProperty() to every field gets old. Turn on the Swagger CLI
plugin and it’ll infer them from your TypeScript types.
// nest-cli.json
{
"compilerOptions": {
"plugins": ["@nestjs/swagger"]
}
} With this on, plain TypeScript classes generate accurate schemas. You still add decorators for examples, descriptions, or overriding types — but you skip the boilerplate.
Exporting the Spec
Want to share the OpenAPI JSON with a frontend team or feed it to a client generator?
import { writeFileSync } from 'fs';
writeFileSync('./openapi.json', JSON.stringify(doc, null, 2)); Drop that into your build and tools like openapi-typescript will give
your frontend fully-typed API clients for free.